Зачем нужен event loop?
Что проверяют
Понимаете ли вы, что JavaScript однопоточный и без цикла событий любая долгая операция замораживала бы страницу.
Как отвечать
У JavaScript один поток и один стек вызовов. Пока выполняется код, ничего другого не происходит: ни отрисовки, ни обработки клика. Если бы запрос к серверу ждали прямо в этом потоке, вкладка зависала бы на всё время ожидания.
Цикл событий решает эту задачу. Долгие операции выполняет не язык, а окружение: браузер или Node отдают их своим механизмам (сеть, таймеры, файловая система), а результат кладут в очередь. Цикл событий берёт задачу из очереди только когда стек пуст, и передаёт управление в код.
Очередей две, и это спрашивают следом:
- микрозадачи: промисы,
queueMicrotask. Выполняются все подряд сразу после текущего синхронного кода; - макрозадачи: таймеры, события, сетевые обработчики. Берётся по одной, между ними браузер успевает отрисовать кадр.
setTimeout(() => console.log("timeout"));
Promise.resolve().then(() => console.log("promise"));
console.log("sync");
// sync, promise, timeoutОтсюда практический вывод: тяжёлый расчёт в обработчике блокирует всё, включая отрисовку, потому что цикл не получит управление. Лечится разбиением на части или выносом в Web Worker.
Где спотыкаются
Считают, что асинхронность создаёт потоки.
Не могут объяснить порядок вывода в примере с таймером и промисом.
Думают, что setTimeout(fn, 0) выполнится немедленно.
Не связывают зависание интерфейса с занятым стеком.