В примере ниже консоль выведет 1 → 4 → 3 → 2. Сначала выполняется синхронный код, затем обработчик выполненного промиса из очереди микрозадач, после него — колбэк таймера. Нулевая задержка setTimeout не означает немедленный вызов.
Event Loop: что и в каком порядке появится в консоли?
Разберите порядок вывода на примере console.log, Promise.then и setTimeout: где заканчивается синхронное выполнение и когда запускаются отложенные обработчики.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Код задачи
Рассмотрим запуск этого фрагмента как одного скрипта в браузере:
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
Почему сообщения появляются в таком порядке
- Текущий скрипт выполняется до конца. Первый
console.logвыводит1. ВызовsetTimeoutрегистрирует таймер, но не запускает его колбэк. Промис уже выполнен, поэтому.thenставит обработчик в очередь микрозадач. Последняя строка выводит4. - На контрольной точке обрабатываются микрозадачи. После завершения скрипта стек вызовов пуст. Выполняется обработчик
.then, и в консоль попадает3. - Затем может выполниться задача таймера. Её колбэк выводит
2. Он не прерывает ни текущий скрипт, ни обработку очереди микрозадач.
Что важно не перепутать
- В браузере обработчики промисов,
queueMicrotaskи доставка уведомленийMutationObserverиспользуют микрозадачи. КолбэкsetTimeoutвыполняется как отдельная задача, которую часто называют макрозадачей. - На контрольной точке очередь микрозадач обрабатывается до опустошения, включая добавленные в процессе микрозадачи. Бесконечная цепочка может задерживать таймеры и отрисовку.
- Задержка
0не гарантирует запуск ровно через ноль миллисекунд: таймер ожидает возможности выполнения.
Для другой задачи сначала отметьте синхронные вызовы, затем проследите, когда именно каждый отложенный обработчик становится готовым. Не переносите порядок этого примера на любой код с промисами: у ещё не завершившегося промиса обработчик пока не готов к запуску.