Как ответить
Event Loop — это механизм, который позволяет JavaScript выполнять асинхронные задачи в однопоточном режиме. Он постоянно проверяет стек вызовов и очередь задач: если стек пуст, цикл берет первую задачу из очереди и переносит её в стек на выполнение. Это позволяет движку не блокироваться на тяжелых операциях ввода-вывода или сетевых запросах.
Весь процесс строится вокруг взаимодействия нескольких структур данных:
- Call Stack (Стек вызовов): сюда попадают функции при вызове. Если функция вызывает другую, та ложится сверху. JavaScript выполняет только то, что находится на вершине стека.
- Web APIs / Node.js APIs: когда мы вызываем
setTimeoutилиfetch, выполнение уходит в фоновые потоки браузера или системы. Движок JS не ждет ответа, а продолжает работать дальше. - Task Queue (Очередь макрозадач): сюда попадают колбэки от
setTimeout,setIntervalи события отрисовки. - Microtask Queue (Очередь микрозадач): здесь живут промисы (
.then,.catch,.finally) иqueueMicrotask.
Критически важно понимать приоритетность. За один итерационный цикл (тик) Event Loop работает так: сначала полностью очищается стек вызовов. Затем выполняется вся очередь микрозадач, которая накопилась к этому моменту. Только после этого движок берет одну задачу из очереди макрозадач и выполняет её. Если в процессе выполнения микрозадачи добавятся новые микрозадачи, они тоже будут выполнены в этом же цикле до перехода к следующей макрозадаче.
Пример для понимания порядка выполнения:
console.log('1'); // Сразу в стек
setTimeout(() => console.log('2'), 0); // В макрозадачи
Promise.resolve().then(() => console.log('3')); // В микрозадачи
console.log('4'); // Сразу в стек
// Вывод: 1, 4, 3, 2В этом примере 3 выведется раньше 2, потому что очередь микрозадач имеет приоритет перед макрозадачами. Также стоит помнить, что рендеринг страницы обычно происходит между макрозадачами, поэтому тяжелые вычисления в микрозадачах могут «подвесить» интерфейс точно так же, как и синхронный код.