Как event loop обрабатывает задачи и куда попадают задачи при выполнении
Что проверяют
Можете ли вы предсказать порядок выполнения асинхронного кода и объяснить его, а не заучить вывод Start, End, Promise, Timeout. Следом обычно дают задачку с async/await и спрашивают, где в этой схеме отрисовка.
Как отвечать
JavaScript выполняет код в одном потоке с одним стеком вызовов. Таймеры, сеть и события обслуживает браузер, а колбэки возвращает в очереди:
- задачи (macrotasks): колбэки
setTimeoutиsetInterval, события ввода,postMessage,MessageChannel, сетевые события. Очередей задач у браузера несколько, и ввод пользователя он может обслужить раньше таймера; - микрозадачи: реакции промисов (
then,catch,finally), продолжение функции послеawait,queueMicrotask,MutationObserver; - отрисовка: колбэки
requestAnimationFrame, затем стили, layout и paint. Это отдельный шаг, а не очередь.
Цикл такой: взять одну задачу и выполнить до конца, затем выполнить все микрозадачи, включая добавленные по ходу, затем, если браузер решил обновить кадр, вызвать requestAnimationFrame и отрисовать. После этого следующая задача. При 60 Гц на кадр около 16,7 мс, а задача дольше 50 мс уже считается long task и заметно тормозит интерфейс.
Про async скажите отдельно: тело функции до первого await выполняется синхронно, всё после него попадает в микрозадачу. Если спросят про Node.js, там свои фазы (timers, poll, check), process.nextTick выполняется раньше промисов, а setImmediate идёт в фазе check.
Тяжёлые вычисления выносят в Web Worker или дробят на куски, отдавая поток между задачами.
Где спотыкаются
Считают, что колбэк в new Promise(...) асинхронный. Исполнитель промиса запускается сразу, асинхронны только обработчики then.
Думают, что микрозадачи выполняются по одной между задачами. Очередь вычерпывается полностью, и бесконечная цепочка микрозадач повесит страницу так же, как while (true).
Уверены, что setTimeout(fn, 0) сработает немедленно. Это минимальная задержка: колбэк ждёт опустошения стека и микрозадач, при вложенности глубже пяти уровней браузер поднимает её до 4 мс, а в фоновой вкладке таймеры сильно замедляются.