← Назад к вопросам

Что отвечает за последовательность вызовов в Node.js?

2.0 Middle🔥 181 комментариев
#Node.js и JavaScript

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Event Loop и последовательность вызовов в Node.js

Event Loop — сердце асинхронности

Event Loop отвечает за управление последовательностью выполнения кода в Node.js. Это однопоточный механизм, который координирует выполнение JavaScript кода, асинхронных операций (I/O, таймеры, promises) и callbacks.

Фазы Event Loop

Event Loop проходит через несколько фаз в каждой итерации:

timers: выполняет callbacks setTimeout/setInterval
pending callbacks: отложенные I/O callbacks
idle, prepare: внутренние операции
poll: ожидает I/O событий
check: выполняет setImmediate callbacks
close: закрывает соединения

Очереди (Queues) и Priority

Внутри Event Loop несколько очередей с разными приоритетами:

1. Microtask Queue (высокий приоритет)

  • Promise.then(), Promise.catch(), Promise.finally()
  • process.nextTick()
  • MutationObserver (в браузере)

2. Macrotask Queue (низкий приоритет)

  • setTimeout(), setInterval()
  • setImmediate()
  • I/O операции (read, write)
console.log('start');

setTimeout(() => console.log('setTimeout'), 0);
setImmediate(() => console.log('setImmediate'), 0);

Promise.resolve().then(() => console.log('promise'));
process.nextTick(() => console.log('nextTick'));

console.log('end');

// Вывод:
// start
// end
// nextTick (microtask)
// promise (microtask)
// setTimeout (macrotask)
// setImmediate (macrotask)

process.nextTick vs setImmediate

process.nextTick(() => console.log('nextTick 1'));
Promise.resolve().then(() => console.log('promise'));
setImmediate(() => console.log('setImmediate'));

// Вывод:
// nextTick 1
// promise
// setImmediate

Практический пример

const fs = require('fs');

console.log('start');

fs.readFile('./file.txt', () => {
  console.log('readFile');
  Promise.resolve().then(() => console.log('promise in readFile'));
  setImmediate(() => console.log('setImmediate in readFile'));
});

setTimeout(() => console.log('setTimeout'), 0);
setImmediate(() => console.log('setImmediate'));
process.nextTick(() => console.log('nextTick'));
Promise.resolve().then(() => console.log('promise'));

console.log('end');

// Вывод:
// start
// end
// nextTick
// promise
// setTimeout
// setImmediate
// readFile (из poll фазы)
// promise in readFile
// setImmediate in readFile

Ключевые моменты

  • process.nextTick() выполняется в конце текущей фазы, но ДО перемещения на следующую фазу
  • Promises (microtasks) выполняются после всех nextTick в очереди
  • setImmediate() выполняется в следующей итерации Event Loop в check фазе
  • setTimeout(..., 0) выполняется в timers фазе, но только если минимум 1ms прошло

Понимание Event Loop критично для написания правильного асинхронного кода и отладки race conditions в Node.js приложениях.

Что отвечает за последовательность вызовов в Node.js? | PrepBro