Назад к вопросам
Middle+
122
questionbank

Расскажите о механизме работы цикла событий (Event Loop) в Node.js.

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Event Loop позволяет Node.js выполнять неблокирующие операции ввода-вывода, несмотря на то, что JavaScript однопоточный. Он постоянно опрашивает очередь событий и выполняет колбэки.

Основные фазы Event Loop'а (в порядке исполнения):

  • timers: Выполняет колбэки для setTimeout() и setInterval().
  • pending callbacks: Обрабатывает операции, запланированные на следующую итерацию цикла.
  • idle, prepare: Используется внутренней логикой Node.js.
  • poll: Основная фаза. Ждет новых событий ввода-вывода, выполняет колбэки для них. При необходимости может блокироваться, если нет активных таймеров или setImmediate() колбэков.
  • check: Выполняет колбэки для setImmediate().
  • close callbacks: Обрабатывает колбэки закрытия, например, socket.on('close', ...).

После каждой фазы цикла событий Node.js проверяет микрозадачи:

  1. process.nextTick(): Колбэки, запланированные с помощью process.nextTick(), выполняются до любых других микрозадач или перехода к следующей фазе Event Loop'а.
  2. Promise callbacks: Колбэки промисов (.then(), .catch(), .finally()) и await выполняются после process.nextTick() и перед следующей фазой Event Loop'а.

Пример работы Event Loop:

// Планируется в фазе timers следующего цикла
setTimeout(() => {
  console.log('Таймер (фаза timers)');
}, 0);

// Планируется в фазе check следующего цикла
setImmediate(() => {
  console.log('Немедленный (фаза check)');
});

// Выполняется сразу в текущей очереди микрозадач
process.nextTick(() => {
  console.log('Next Tick (микрозадача)');
});

// промис также добавляет колбэки в очередь микрозадач
Promise.resolve().then(() => {
  console.log('Промис (микрозадача)');
});

console.log('Начало выполнения (сразу)');

Ожидаемый вывод:

Начало выполнения (сразу)
Next Tick (микрозадача)
Промис (микрозадача)
Таймер (фаза timers) // Может появиться раньше или позже "Немедленный", зависит от загрузки
Немедленный (фаза check) // Может появиться раньше или позже "Таймер", зависит от загрузки

Event Loop управляется библиотекой libuv, которая предоставляет абстракцию над низкоуровневыми операциями ввода-вывода и механизмами планирования задач в операционной системе.