> Что такое event loop в JavaScript и как он работает с микрозадачами и макрозадачами (JavaScript)
Уровень: junior · Роль: frontend · Язык: JavaScript · Категория: Технические вопросы
Компании: ЭНИРАН
Стек: Node.js, JavaScript
> Пример ответа
Короткий ответ
Event loop - это механизм, который позволяет JavaScript выполнять асинхронный код в однопоточном окружении. Он постоянно проверяет, есть ли задачи в очереди, и передаёт их на выполнение. Макрозадачи (setTimeout, setInterval, I/O) обрабатываются по одной за цикл, а микрозадачи (Promise.then, queueMicrotask) - все сразу после каждой макрозадачи, перед рендерингом и следующей макрозадачей.
Подробное объяснение
JavaScript - однопоточный язык с одним call stack. Event loop управляет порядком выполнения кода, используя две очереди: macrotask queue и microtask queue.
Макрозадачи включают: setTimeout, setInterval, setImmediate (Node.js), I/O, UI rendering (браузер). Они добавляются в очередь макрозадач и выполняются по одной за итерацию event loop.
Микрозадачи включают: Promise.then/catch/finally, queueMicrotask, MutationObserver (браузер), process.nextTick (Node.js). После завершения каждой макрозадачи event loop обрабатывает всю очередь микрозадач до опустошения, прежде чем перейти к следующей макрозадаче или рендерингу.
Алгоритм работы event loop:
- Выполнить синхронный код (весь скрипт - это макрозадача).
- Обработать все микрозадачи из очереди.
- Выполнить рендеринг (если нужно).
- Взять следующую макрозадачу из очереди.
- Повторить.
Это гарантирует, что микрозадачи всегда выполняются раньше, чем следующая макрозадача, что критично для Promise и асинхронных операций.
На практике
Понимание event loop важно для:
- Предсказания порядка выполнения асинхронного кода.
- Избежания блокировки UI из-за долгих микрозадач.
- Оптимизации производительности (например, разбивка тяжёлых задач на макрозадачи через setTimeout).
- Работы с Promise, async/await и очередями в Node.js.
Пример: если в цикле создавать много Promise, их колбэки (микрозадачи) выполнятся все сразу после текущей макрозадачи, что может заблокировать рендеринг или I/O.
Пример кода
JAVASCRIPTconsole.log('1: синхронный код');setTimeout(() => {console.log('2: макрозадача setTimeout');}, 0);Promise.resolve().then(() => {console.log('3: микрозадача Promise');});queueMicrotask(() => {console.log('4: микрозадача queueMicrotask');});console.log('5: ещё синхронный код');// Вывод:// 1: синхронный код// 5: ещё синхронный код// 3: микрозадача Promise// 4: микрозадача queueMicrotask// 2: макрозадача setTimeout
Как отвечать на собеседовании
Начни с краткого определения event loop как механизма управления асинхронностью. Объясни разницу между макро- и микрозадачами, приведи примеры. Опиши порядок выполнения: синхронный код → микрозадачи → макрозадачи. Покажи понимание, что микрозадачи блокируют выполнение макрозадач, если их много. Используй простой пример с Promise и setTimeout. Не углубляйся в детали Node.js (setImmediate, process.nextTick), если не спрашивают.
Что проверяет интервьюер
- Понимание асинхронной модели JavaScript.
- Знание очередей задач и приоритетов.
- Умение предсказывать порядок выполнения кода.
- Осознание практических последствий (блокировка, производительность).
- Базовое понимание event loop в браузере и Node.js.
Типичные ошибки
- Путать макро- и микрозадачи (например, считать Promise макрозадачей).
- Думать, что setTimeout с задержкой 0 выполняется сразу после синхронного кода.
- Не учитывать, что микрозадачи обрабатываются до следующей макрозадачи.
- Считать, что event loop - это часть языка, а не окружения (браузер/Node.js).
- Забывать про queueMicrotask и process.nextTick как микрозадачи.
> Похожие задачи по JavaScript
Как использовать асинхронные функции при переборе элементов, например в reduce
Как вы писали модульные и интеграционные тесты
Нужно ли добавлять Promise к выходному типу асинхронной функции в TypeScript
Можно ли создать два интерфейса или типа с одинаковым именем, но разным описанием в TypeScript
> Похожие задачи по frontend
Как использовать асинхронные функции при переборе элементов, например в reduce
Как вы писали модульные и интеграционные тесты
Как определить тип переменной через ReturnType в TypeScript
Что такое Composition API во Vue и в чем разница с Options API
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью