Само объявление execute ничего не печатает. После execute() в браузере вывод будет: 1, Promise, 4, timeOut, 777, then1, then2, timeOut2. Исполнитель Promise синхронный; после таймера с resolve() обе реакции then выполняются как микрозадачи до перехода к следующему таймеру.
В каком порядке выполнятся таймеры и цепочка then внутри execute?
Задача на Event Loop: синхронный исполнитель Promise, три таймера и две микрозадачи then. Разбираем вывод после вызова execute в браузере.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В каком порядке появятся сообщения при вызове этой функции в браузере?
const execute = () => {
setTimeout(() => console.log('timeOut'), 0);
console.log(1);
new Promise((resolve) => {
console.log('Promise');
setTimeout(() => {
console.log('777');
resolve();
}, 0);
})
.then(() => console.log('then1'))
.then(() => console.log('then2'));
console.log(4);
setTimeout(() => console.log('timeOut2'), 0);
};
Одно объявление функции ничего не выводит. В условии подразумевается последующий вызов execute().
Результат вызова
1
Promise
4
timeOut
777
then1
then2
timeOut2
Пошаговый разбор
- Регистрируется первый таймер. Он не прерывает текущий синхронный код.
- Печатается
1. Исполнительnew Promiseвызывается немедленно: появляетсяPromiseи регистрируется второй таймер. Промис пока не выполнен. - Цепочка
.thenподписывается на результат, но её обработчики ещё не запускаются. Печатается4и регистрируется третий таймер. - Первый таймер выводит
timeOut. - Второй таймер выводит
777и вызываетresolve(). Реакция первого.thenпопадает в очередь микрозадач. - На контрольной точке микрозадач выполняется первый обработчик и печатает
then1. Его завершение разрешает следующий промис в цепочке, поэтому добавляется и выполняется микрозадача сthen2. Очередь очищается до следующей задачи таймера. - Третий таймер печатает
timeOut2.
Что важно не перепутать
setTimeout(..., 0) означает планирование задачи, а не немедленный вызов. new Promise сам по себе не переносит свой исполнитель в фон. В этой задаче оба then выполняются между вторым и третьим таймерами, а не после всех таймеров.
Вывод относится к приведённому фрагменту без другого вмешивающегося кода и к браузерному Event Loop. Нулевая задержка не обещает точное время в миллисекундах. Для обсуждения другой среды, например Node.js с дополнительными очередями, сначала нужно зафиксировать её условия. Правила браузерных таймеров описаны в HTML Standard.