> Что такое event loop в JavaScript и как он работает с микрозадачами и макрозадачами (JavaScript)
Уровень: junior · Роль: frontend · Категория: Технические вопросы
Компании: amoCRM, Иннотех, Cyber Interactive, Альфа-банк, YADRO, Garage Eight, Kvando Technologies, циан, Soft_Media_Group, ООО Премиум ИТ Солюшен, VK, Kodix, РСХБ, LeverX, Инити, Aston, Газпромбанк, Домклик, IT-One, Софт Медиа Групп, МТГ Бизнес решения, Библио-Глобус, Rutube, Дом.рф, intelsy, Avito, Сфера, EdenAI, Сбер, Арго, TYMY, 1221 Systems, Исходный Код, Globaldrive, Кэтрид Диджитал, SmartWay, ООО Снэп АйТи
Стек: JavaScript
> Пример ответа
Короткий ответ
Event loop - это механизм в JavaScript, который управляет порядком выполнения кода, обрабатывая очередь задач. Он позволяет синхронному языку работать асинхронно: сначала выполняются все синхронные операции, затем микрозадачи (promises, queueMicrotask), и только потом макрозадачи (setTimeout, setInterval, I/O). Микрозадачи всегда выполняются до следующей макрозадачи, что гарантирует предсказуемый порядок асинхронных операций.
Подробное объяснение
JavaScript - однопоточный язык с одним call stack. Event loop - это бесконечный цикл, который проверяет, пуст ли call stack, и если да, берёт задачи из очередей.
Существует две очереди:
- Микрозадачи - создаются через
Promise.then,catch,finally,queueMicrotask,async/await(послеawait). Они имеют приоритет. - Макрозадачи - создаются через
setTimeout,setInterval,setImmediate,I/O, рендеринг браузера.
Алгоритм работы event loop:
- Выполнить весь синхронный код (текущий call stack).
- После того как стек пуст, выполнить все микрозадачи из очереди (по одной, но до полного опустошения).
- Взять одну макрозадачу из очереди и выполнить её.
- После выполнения макрозадачи снова проверить микрозадачи - если появились новые, выполнить их все.
- Повторять цикл.
Важный момент: если микрозадача создаёт новую микрозадачу, она будет выполнена в той же итерации, до перехода к макрозадачам. Это может привести к "голоданию" макрозадач, если микрозадачи создаются бесконечно.
Рендеринг браузера происходит между макрозадачами, но после микрозадач. Поэтому если вы обновляете DOM в микрозадаче, браузер может не успеть отрисовать до следующей макрозадачи.
На практике
Понимание event loop критично для:
- отладки асинхронного кода - порядок выполнения не всегда очевиден;
- оптимизации производительности - тяжёлые операции в микрозадачах блокируют рендеринг;
- работы с
async/await-awaitвсегда создаёт микрозадачу, даже если промис уже resolved; - избегания deadlock-подобных ситуаций, когда микрозадачи бесконечно порождают себя.
Пример кода
JAVASCRIPTconsole.log('1: синхронный');setTimeout(() => {console.log('2: макрозадача');}, 0);Promise.resolve().then(() => {console.log('3: микрозадача');}).then(() => {console.log('4: ещё микрозадача');});queueMicrotask(() => {console.log('5: queueMicrotask');});console.log('6: синхронный конец');// Вывод:// 1: синхронный// 6: синхронный конец// 3: микрозадача// 4: ещё микрозадача// 5: queueMicrotask// 2: макрозадача
Обратите внимание: все микрозадачи выполняются до макрозадачи, даже если setTimeout с нулевой задержкой был вызван раньше.
Как отвечать на собеседовании
Начните с простого определения, затем опишите порядок выполнения. Обязательно упомяните, что микрозадачи имеют приоритет над макрозадачами. Приведите пример с setTimeout и Promise. Если спросят про async/await - скажите, что await - это синтаксический сахар над промисами, и он тоже создаёт микрозадачу.
Для уровня junior достаточно объяснить базовый механизм и порядок. Не углубляйтесь в детали реализации V8 или Node.js, если не спрашивают.
Что проверяет интервьюер
- Понимание однопоточной модели JavaScript.
- Знание разницы между микрозадачами и макрозадачами.
- Умение предсказать порядок вывода в асинхронном коде.
- Понимание, почему
setTimeout(0)не гарантирует немедленное выполнение. - Осознание влияния event loop на производительность и рендеринг.
Типичные ошибки
- Утверждение, что
setTimeout(0)выполнится сразу после синхронного кода - на самом деле после всех микрозадач. - Забывают, что микрозадачи выполняются все подряд, а макрозадачи - по одной за итерацию.
- Путают порядок: думают, что макрозадачи и микрозадачи чередуются.
- Не знают, что
awaitвсегда создаёт микрозадачу, даже если промис уже resolved. - Считают, что event loop - это часть языка JavaScript, хотя это часть окружения (браузер или Node.js).
> Похожие задачи по frontend
Что такое каррирование
Что такое контекст (this) в JavaScript
Как реализовать в HTTP заголовках сервис, который принимает JSON и отвечает текстом
Как реализована отправка JSON в API
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью