Skip to main content
Практика завдань

У чому різниця між process.nextTick() та setImmediate()?

process.nextTick() vs setImmediate()

Обидва використовуються для планування асинхронних зворотних викликів у Node.js, але вони працюють на різних етапах циклу подій і мають різні пріоритети.


process.nextTick()

Виконується одразу після завершення поточної операції, перед тим як цикл подій перейде до наступного етапу. Має найвищий пріоритет серед усіх механізмів асинхронного планування.

js
console.log('1 - початок'); process.nextTick(() => { console.log('2 - nextTick'); }); console.log('3 - кінець'); // Вихід: // 1 - початок // 3 - кінець // 2 - nextTick

Основні характеристики:

  • Виконується перед будь-якими I/O подіями або таймерами
  • Виконується в мікротасковій черзі (так само, як і виконані Promises)
  • Рекурсивний nextTick може призвести до голодування I/O — будьте обережні!
js
// ⚠️ Це призведе до голодування I/O — зворотний виклик виконується вічно function recursiveNextTick() { process.nextTick(recursiveNextTick); } recursiveNextTick(); // setTimeout, setImmediate, I/O НІКОЛИ не спрацюють

setImmediate()

Виконується на наступній ітерації циклу подій, зокрема на етапі перевірки — після завершення етапу опитування I/O.

js
console.log('1 - початок'); setImmediate(() => { console.log('2 - setImmediate'); }); console.log('3 - кінець'); // Вихід: // 1 - початок // 3 - кінець // 2 - setImmediate

Основні характеристики:

  • Виконується на етапі перевірки циклу подій
  • Не призводить до голодування I/O — завжди спочатку віддає перевагу очікуючому I/O
  • Рекомендується для відкладення роботи на наступну ітерацію

Порівняння боком до боку

js
setImmediate(() => console.log('setImmediate')); process.nextTick(() => console.log('nextTick')); Promise.resolve().then(() => console.log('Promise')); // Вихід (завжди): // nextTick // Promise // setImmediate

Порядок пріоритету циклу подій

ПріоритетМеханізмЧерга
1 (найвищий)process.nextTick()Мікротаск
2Promise.then()Мікротаск
3setTimeout(fn, 0)Фаза таймерів
4setImmediate()Фаза перевірки

Усередині зворотного виклику I/O

Коли викликається всередині зворотного виклику I/O, setImmediate завжди виконується перед setTimeout:

js
const fs = require('fs'); fs.readFile(__filename, () => { setTimeout(() => console.log('setTimeout'), 0); setImmediate(() => console.log('setImmediate')); }); // Вихід (завжди): // setImmediate // setTimeout

Коли використовувати що?

Сценарій використанняРекомендація
Має виконуватися перед будь-яким I/Oprocess.nextTick()
Відкласти на наступну ітерацію циклу подійsetImmediate()
Після завершення I/OsetImmediate()
Випускати події після конструктораprocess.nextTick()
js
const EventEmitter = require('events'); class MyEmitter extends EventEmitter { constructor() { super(); // Випустити після повернення конструктора, щоб слухачі могли підключитися process.nextTick(() => { this.emit('ready'); }); } } const emitter = new MyEmitter(); emitter.on('ready', () => console.log('готово!')); // Працює! 'готово!' виводиться

Найкраща практика: Використовуйте setImmediate() за замовчуванням. Залиште process.nextTick() для випадків, коли вам потрібно виконати код перед будь-яким I/O, і уникайте рекурсивних викликів nextTick, щоб запобігти голодуванню I/O.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань