Гарантированное начало: Start, async request, End, Promise 1, Promise 2. Относительный порядок Timeout 1 и callbacks requestAnimationFrame зависит от момента обновления рендеринга браузера.
Определение последовательности вывода сообщений в консоль при сочетании setTimeout, Promise и requestAnimationFrame
Гарантированное начало: Start, async request, End, Promise 1, Promise 2. Относительный порядок Timeout 1 и callbacks requestAnimationFrame зависит от момента обновления рендеринга браузера.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Нужно понять, в каком порядке появятся записи в консоли при выполнении следующего JavaScript‑кода, где задействованы setTimeout, Promise и requestAnimationFrame.
console.log('Start');
setTimeout(() => {
console.log('Timeout 1');
}, 0);
new Promise((resolve, _) => {
console.log('async request');
resolve();
})
.then(() => {
console.log('Promise 1');
})
.then(() => {
console.log('Promise 2');
});
requestAnimationFrame(() => {
console.log('requestAnimationFrame 1');
});
requestAnimationFrame(() => {
console.log('requestAnimationFrame 2');
});
console.log('End');
Ответ
Гарантированное начало: Start, async request, End, Promise 1, Promise 2. Относительный порядок Timeout 1 и callbacks requestAnimationFrame зависит от момента обновления рендеринга браузера.
Executor конструктора Promise вызывается синхронно, поэтому async request появляется до End. Обработчики then выполняются в очереди микрозадач: второй ставится после завершения первого.
В обычном активном документе два зарегистрированных requestAnimationFrame выполняются в порядке регистрации: сначала 1, затем 2. Но нельзя гарантировать, что нулевой таймер будет обязательно до них или после: таймер — отдельная задача, а кадр связан с возможностью обновления рендеринга. В фоновой вкладке callbacks кадров могут долго не выполняться. Для Node.js этот код без предоставленного requestAnimationFrame вообще не является тем же окружением.