Чем отличаются nextTick, setImmediate и setTimeout?nodejs-27

Эти три функции относятся к разным фазам Event Loop в Node.js и имеют ключевые различия в поведении. Рассмотрим каждую из них подробно.

process.nextTick

process.nextTick(() => {
  console.log('Выполнится в текущей фазе Event Loop');
});
  • Когда выполняется: В конце текущей операции (перед переходом к следующей фазе Event Loop).
  • Очередь: Имеет собственную очередь, которая обрабатывается после текущей операции.
  • Приоритет: Самый высокий среди рассматриваемых - выполнится раньше setImmediate и setTimeout.
  • Использование: Для отложенного выполнения кода, который должен запуститься сразу после текущего синхронного кода.

setImmediate

setImmediate(() => {
  console.log('Выполнится в фазе check Event Loop');
});
  • Когда выполняется: В фазе "check" Event Loop (после фазы poll).
  • Очередь: Помещается в очередь фазы "check".
  • Приоритет: Ниже, чем у nextTick, но выше, чем у setTimeout(..., 0).
  • Использование: Для выполнения кода, который должен запуститься после завершения текущего Event Loop.

setTimeout

setTimeout(() => {
  console.log('Выполнится в фазе timers');
}, 0);
  • Когда выполняется: В фазе "timers" Event Loop.
  • Очередь: Помещается в очередь таймеров.
  • Приоритет: Самый низкий среди рассматриваемых (при одинаковой задержке 0).
  • Использование: Для выполнения кода после истечения указанного времени (даже если указано 0).

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

console.log('Start');

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

console.log('End');

Вывод будет:

Start
End
nextTick
setTimeout
setImmediate

Почему такой порядок?

  1. Сначала выполняется весь синхронный код
  2. Затем обрабатывается очередь nextTick
  3. Потом фаза timers (setTimeout)
  4. И только затем фаза check (setImmediate)

Особенности в разных контекстах

Внутри I/O цикла порядок может измениться:

const fs = require('fs');

fs.readFile(__filename, () => {
  setTimeout(() => console.log('timeout'), 0);
  setImmediate(() => console.log('immediate'));
  process.nextTick(() => console.log('nextTick'));
});

Вывод:

nextTick
immediate
timeout

Резюмируем

  • nextTick - выполняется сразу после текущей операции, вне Event Loop
  • setImmediate - выполняется в фазе "check" Event Loop
  • setTimeout - выполняется в фазе "timers" Event Loop
  • Приоритет выполнения: nextTick > setImmediate > setTimeout (при задержке 0)