Чем отличаются 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
Почему такой порядок?
- Сначала выполняется весь синхронный код
- Затем обрабатывается очередь nextTick
- Потом фаза timers (setTimeout)
- И только затем фаза 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)