Как работает event loop в JavaScript — макрозадачи и микрозадачи?
- В каком порядке выполнятся setTimeout и Promise.then?
- Почему долгий цикл замораживает страницу?
JavaScript выполняется в одном потоке. Цикл событий берёт одну макрозадачу (скрипт, setTimeout, событие, сетевой ответ), выполняет её до конца, затем все микрозадачи (then у промисов, await-продолжения, queueMicrotask), затем при необходимости отрисовку, и берёт следующую макрозадачу.
- Promise.then всегда раньше setTimeout(..., 0)
- Долгий синхронный код блокирует и обработку событий, и отрисовку
- Бесконечная цепочка микрозадач тоже замораживает страницу
А ещё Тяжёлые вычисления — в Web Worker
Подробно
Компоненты:
- стек вызовов — выполняемый сейчас синхронный код;
- Web API браузера (таймеры, сеть, DOM-события) работают вне потока JS и ставят колбэки в очереди;
- очередь макрозадач — колбэки таймеров, событий, сообщений;
- очередь микрозадач — продолжения промисов, MutationObserver.
Один оборот: выполнить макрозадачу → опустошить очередь микрозадач (включая добавленные по ходу) → если пора, отрисовать кадр (requestAnimationFrame, стили, раскладка, отрисовка) → следующая макрозадача.
Следствия: setTimeout(fn, 0) — не «сразу», а «после текущей задачи и всех микрозадач»; минимальная задержка вложенных таймеров — 4 мс; фоновые вкладки замедляют таймеры.
Не блокировать поток: разбивать работу на части (setTimeout, scheduler.yield), выносить в Web Worker.
Пример
console.log(1);
setTimeout(() => console.log(2));
Promise.resolve().then(() => console.log(3));
queueMicrotask(() => console.log(4));
console.log(5);
// 1 5 3 4 2Что хотят услышать
- Однопоточность и роль Web API.
- Порядок макро- и микрозадач.
- Место отрисовки и почему важно не блокировать поток.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗setTimeout(fn, 0) выполняется раньше Promise.then, потому что таймер был поставлен в очередь первым
- ✓Макрозадача, затем все микрозадачи, затем отрисовка; поэтому Promise.then раньше setTimeout
- ✗JavaScript выполняет макрозадачи в нескольких потоках параллельно
- ✗Микрозадачи выполняются после отрисовки, по одной между макрозадачами
Что спросят дальше
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.