Вопрос проверяет понимание механизма event loop в JavaScript, включая приоритеты микрозадач (promises) и макрозадач (setTimeout), а также влияние рекурсивных вызовов на порядок выполнения.
Event loop в JavaScript управляет выполнением кода, обрабатывая очередь задач. Задачи делятся на два типа: микрозадачи (promises, mutation observers) и макрозадачи (setTimeout, setInterval, I/O). На каждом цикле event loop сначала обрабатывается одна макрозадача, затем все микрозадачи, и только потом следующая макрозадача.
Если внутри промиса рекурсивно создается новый промис, он добавляется в очередь микрозадач. Event loop будет выполнять все микрозадачи до опустошения очереди, прежде чем перейти к следующей макрозадаче. Это означает, что вложенные setTimeout не будут выполнены, пока не завершатся все рекурсивные промисы.
let count = 0;
function recursivePromise() {
return new Promise((resolve) => {
console.log('Promise', count);
count++;
if (count < 5) {
resolve(recursivePromise());
} else {
resolve('done');
}
});
}
setTimeout(() => console.log('Timeout 1'), 0);
setTimeout(() => console.log('Timeout 2'), 0);
recursivePromise().then(console.log);
// Вывод:
// Promise 0
// Promise 1
// Promise 2
// Promise 3
// Promise 4
// done
// Timeout 1
// Timeout 2Понимание этого механизма важно для предотвращения блокировки интерфейса. Если рекурсивные промисы создаются бесконечно, макрозадачи (например, обработка событий или рендеринг) никогда не выполнятся, что приведет к зависанию приложения.
Вывод: рекурсивные промисы имеют приоритет над setTimeout, поэтому их следует использовать с осторожностью, чтобы не заблокировать event loop. В случаях, когда требуется отложить выполнение, лучше использовать setTimeout или setImmediate.
Frontend developer
Ментор по Frontend
Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства
Записаться на консультацию