Если микрозадача создает новую микрозадачу, в какую очередь она уходит?
Асинхронность и Event Loop
Если микрозадача создаёт новую микрозадачу, она попадает в ту же очередь микрозадач и выполняется в текущем цикле — до того, как Event Loop перейдёт к макрозадачам.
Как это работает
Event Loop опустошает очередь микрозадач полностью, включая те, что добавились во время обработки. Новая микрозадача не ждёт следующего «тика» — она обрабатывается в том же цикле:
Promise.resolve().then(() => {
console.log('1');
Promise.resolve().then(() => console.log('2')); // новая микрозадача
});
setTimeout(() => console.log('3'), 0);
console.log('0');
// 0 → 1 → 2 → 32 (созданная внутри микрозадачи) выполнится до 3 (макрозадача), потому что очередь микрозадач опустошается целиком перед следующей макрозадачей.
Следствие
Бесконечная генерация микрозадач блокирует Event Loop — он никогда не дойдёт до макрозадач и рендеринга:
function loop() {
Promise.resolve().then(loop); // страница зависнет
}
loop();Микрозадачи «не дают дышать» макрозадачам и рендеру.
Отличие от макрозадач
Макрозадача, создающая макрозадачу, — новая идёт в следующий «тик» (по одной за цикл). Микрозадачи же опустошаются все сразу.
Коротко для собеседования
Новая микрозадача, созданная внутри микрозадачи, попадает в ту же очередь и выполняется в текущем цикле — очередь микрозадач опустошается целиком до следующей макрозадачи. Поэтому вложенные .then выполняются раньше setTimeout. Бесконечная генерация микрозадач блокирует макрозадачи и рендеринг.