Node.js version 0.10 was released today and introduced setImmediate
. The API changes documentation suggests using it when doing recursive nextTick
Some great answers here detailing how they both work.
Just adding one that answers the specific question asked:
When should I use
nextTick
and when should I usesetImmediate
?
setImmediate
.The Node.js Event Loop, Timers, and process.nextTick() doc includes the following:
We recommend developers use
setImmediate()
in all cases because it's easier to reason about (and it leads to code that's compatible with a wider variety of environments, like browser JS.)
Earlier in the doc it warns that process.nextTick
can lead to...
some bad situations because it allows you to "starve" your I/O by making recursive
process.nextTick()
calls, which prevents the event loop from reaching the poll phase.
As it turns out, process.nextTick
can even starve Promises
:
Promise.resolve().then(() => { console.log('this happens LAST'); });
process.nextTick(() => {
console.log('all of these...');
process.nextTick(() => {
console.log('...happen before...');
process.nextTick(() => {
console.log('...the Promise ever...');
process.nextTick(() => {
console.log('...has a chance to resolve');
})
})
})
})
On the other hand, setImmediate
is "easier to reason about" and avoids these types of issues:
Promise.resolve().then(() => { console.log('this happens FIRST'); });
setImmediate(() => {
console.log('this happens LAST');
})
So unless there is a specific need for the unique behavior of process.nextTick
, the recommended approach is to "use setImmediate()
in all cases".
Use setImmediate
if you want to queue the function behind whatever I/O event callbacks that are already in the event queue. Use process.nextTick
to effectively queue the function at the head of the event queue so that it executes immediately after the current function completes.
So in a case where you're trying to break up a long running, CPU-bound job using recursion, you would now want to use setImmediate
rather than process.nextTick
to queue the next iteration as otherwise any I/O event callbacks wouldn't get the chance to run between iterations.
In simple terms, process.NextTick() would executed at next tick of event loop. However, the setImmediate, basically has a separate phase which ensures that the callback registered under setImmediate() will be called only after the IO callback and polling phase.
Please refer to this link for nice explanation: https://medium.com/the-node-js-collection/what-you-should-know-to-really-understand-the-node-js-event-loop-and-its-metrics-c4907b19da4c
As an illustration
import fs from 'fs';
import http from 'http';
const options = {
host: 'www.stackoverflow.com',
port: 80,
path: '/index.html'
};
describe('deferredExecution', () => {
it('deferredExecution', (done) => {
console.log('Start');
setTimeout(() => console.log('TO1'), 0);
setImmediate(() => console.log('IM1'));
process.nextTick(() => console.log('NT1'));
setImmediate(() => console.log('IM2'));
process.nextTick(() => console.log('NT2'));
http.get(options, () => console.log('IO1'));
fs.readdir(process.cwd(), () => console.log('IO2'));
setImmediate(() => console.log('IM3'));
process.nextTick(() => console.log('NT3'));
setImmediate(() => console.log('IM4'));
fs.readdir(process.cwd(), () => console.log('IO3'));
console.log('Done');
setTimeout(done, 1500);
});
});
will give the following output
Start
Done
NT1
NT2
NT3
TO1
IO2
IO3
IM1
IM2
IM3
IM4
IO1
I hope this can help to understand the difference.
Updated:
Callbacks deferred with
process.nextTick()
run before any other I/O event is fired, while with setImmediate(), the execution is queued behind any I/O event that is already in the queue.Node.js Design Patterns, by Mario Casciaro (probably the best book about node.js/js)
In the comments in the answer, it does not explicitly state that nextTick shifted from Macrosemantics to Microsemantics.
before node 0.9 (when setImmediate was introduced), nextTick operated at the start of the next callstack.
since node 0.9, nextTick operates at the end of the existing callstack, whereas setImmediate is at the start of the next callstack
check out https://github.com/YuzuJS/setImmediate for tools and details
I recommend you to check docs section dedicated for Loop to get better understanding. Some snippet taken from there:
We have two calls that are similar as far as users are concerned, but their names are confusing.
process.nextTick() fires immediately on the same phase
setImmediate() fires on the following iteration or 'tick' of the
event loop
In essence, the names should be swapped. process.nextTick() fires more immediately than setImmediate(), but this is an artifact of the past which is unlikely to change.