> Каков порядок вывода консольных логов при использовании setTimeout и промисов в JavaScript (JavaScript)
Уровень: middle · Роль: frontend · Категория: Технические вопросы
Компании: amoCRM
Стек: JavaScript
> Пример ответа
Короткий ответ
Порядок вывода определяется event loop: сначала выполняются синхронные задачи, затем микрозадачи (промисы), потом макрозадачи (setTimeout). Таким образом, resolve промиса выведется раньше, чем колбэк setTimeout, даже если таймер установлен на 0 мс.
Подробное объяснение
JavaScript использует однопоточную модель с event loop. Очередь задач делится на три уровня:
- Синхронный код - выполняется сразу в текущем стеке вызовов.
- Микрозадачи (microtasks) - промисы (then/catch/finally), queueMicrotask, MutationObserver. Выполняются сразу после завершения текущего синхронного кода, перед любой макрозадачей.
- Макрозадачи (macrotasks) - setTimeout, setInterval, I/O, UI rendering. Выполняются по одной за цикл event loop.
Когда промис переходит в состояние resolved или rejected, его колбэк попадает в очередь микрозадач. setTimeout добавляет колбэк в очередь макрозадач. Event loop сначала опустошает очередь микрозадач, затем берёт одну макрозадачу.
На практике
Это поведение критично при построении цепочек асинхронных операций. Если нужно гарантировать выполнение после всех микрозадач - используйте setTimeout. Если нужно выполнить код как можно раньше после синхронной части - используйте Promise.resolve().then() или queueMicrotask.
Пример кода
JAVASCRIPTconsole.log('1: синхронный');setTimeout(() => console.log('2: setTimeout'), 0);Promise.resolve().then(() => console.log('3: промис'));console.log('4: синхронный');
Вывод:
1: синхронный 4: синхронный 3: промис 2: setTimeout
Как отвечать на собеседовании
Начни с event loop и разделения на очереди. Объясни, что микрозадачи имеют приоритет над макрозадачами. Приведи пример с setTimeout(0) и промисом. Упомяни, что вложенные микрозадачи (например, then внутри then) выполняются до перехода к следующей макрозадаче. Если спросят про async/await - объясни, что await - это синтаксический сахар над then, и код после await попадает в микрозадачи.
Что проверяет интервьюер
- Понимание event loop и очередей задач
- Различие между микрозадачами и макрозадачами
- Умение предсказывать порядок выполнения асинхронного кода
- Знание приоритетов разных типов асинхронных операций
Типичные ошибки
- Утверждение, что setTimeout(0) выполняется мгновенно
- Игнорирование разницы между микрозадачами и макрозадачами
- Непонимание, что вложенные промисы создают новые микрозадачи
- Путаница между async/await и обычными промисами в контексте event loop
> Похожие задачи по frontend
Какие способы выполнения HTTP-запросов в браузере на JavaScript?
Можно ли отлавливать события на фазе погружения (capture phase) в JavaScript и как это сделать
Как проверить тег элемента в обработчике события клика в JavaScript
Каков порядок выполнения setTimeout и промисов в JavaScript при вложенных вызовах
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью