I\'m very confused about the differences between nextTick and setImmediate. I\'ve read all the documentation about them on the internet but I still don\'t understand how the
I think all the answers above are obsolete, because I got different answers constantly with the current version of nodejs and it is easy to reason about
var log=console.log
log(process.version)
var makeAsyncCall
if(false)
makeAsyncCall=setImmediate
else
makeAsyncCall=process.nextTick;
makeAsyncCall(function A () {
makeAsyncCall(function B() {
log(1);
makeAsyncCall(function C() { log(2); });
makeAsyncCall(function D() { log(3); });
});
makeAsyncCall(function E() {
log(4);
makeAsyncCall(function F() { log(5); });
makeAsyncCall(function G() { log(6); });
});
});
//1
//4
//2
//3
//5
//6
//in both case
After reading https://github.com/nodejs/node/blob/master/doc/topics/the-event-loop-timers-and-nexttick.md#processnexttick-vs-setimmediate
let use start from setImmediate
we should keep track of the check queue
because it is where the setImmediate
callback reside.
First iteration
A
is push to check queue
check queue :[A]
Second iteration
A
is pull out from queue
to execute
During its execution ,it put B
and E
to queue
and then, A
complete and start next iteration
check queue :[B,E]
Third iteration
pull out B
and push C
D
check queue :[E,C,D]
Forth iteration
pull out E
and push F
G
check queue : [C,D,F,G]
Finally
execute the callbacks in the queue sequentially
For nextTick
case, the queue works exactly the same way,that is why it produce same result
The different is that :
the nextTickQueue will be processed after the current operation completes, regardless of the current phase of the event loop
To be clear,the event loop maintain multiple queues and check queue
is just one of them,the node will decide which queue to use based on some rules
with process.nextTick
however,it is sort of bypassing all the rule and execute the callback in nextTick
immediately
I can't reproduce your results for setImmediate
. It should be the same as nextTick
(and it is in my tests) since in this situation they do pretty much the same thing. The only reasonable explanation for that is that setImmediate
is somehow synchronous, but it is not.
And according to NodeJS documentation the only real difference is that multiple nextTick
may fire in one loop iteration (depending on maxTickDepth
), while setImmediate
fires once per iteration.
Consider the following two examples:
setImmediate
setImmediate(function A() {
setImmediate(function B() {
log(1);
setImmediate(function D() { log(2); });
setImmediate(function E() { log(3); });
});
setImmediate(function C() {
log(4);
setImmediate(function F() { log(5); });
setImmediate(function G() { log(6); });
});
});
setTimeout(function timeout() {
console.log('TIMEOUT FIRED');
}, 0)
// 'TIMEOUT FIRED' 1 4 2 3 5 6
// OR
// 1 'TIMEOUT FIRED' 4 2 3 5 6
nextTick
process.nextTick(function A() {
process.nextTick(function B() {
log(1);
process.nextTick(function D() { log(2); });
process.nextTick(function E() { log(3); });
});
process.nextTick(function C() {
log(4);
process.nextTick(function F() { log(5); });
process.nextTick(function G() { log(6); });
});
});
setTimeout(function timeout() {
console.log('TIMEOUT FIRED');
}, 0)
// 1 4 2 3 5 6 'TIMEOUT FIRED'
setImmediate callbacks are fired off the event loop, once per iteration in the order that they were queued. So on the first iteration of the event loop, callback A is fired. Then on the second iteration of the event loop, callback B is fired, then on the third iteration of the event loop callback C is fired, etc. This prevents the event loop from being blocked and allows other I/O or timer callbacks to be called in the mean time (as is the case of the 0ms timeout, which is fired on the 1st or 2nd loop iteration).
nextTick callbacks, however, are always fired immediately after the current code is done executing and BEFORE going back to the event loop. In the nextTick example, we end up executing all the nextTick callbacks before ever returning to the event loop. Since setTimeout's callback will be called from the event loop, the text 'TIMEOUT FIRED' will not be output until we're done with every nextTick callback.
According the Node.js doc names of these two function are exactly swapped
setImmediate() (BEST RECOMMENDED)
It's fire first at event queue
process.nextTick() (USE FOR SPECIAL CASES see example later on)
It's fire immediately, It's kinda write an statement more at the end at the current file
If we have this code
setTimeout(function(){
console.log('Hello world 5'); // It's waiting like a normal person at a queue
}, 0);
setImmediate(function(){
console.log('Hello world 4');
// It's like get to last and be take care of first
// but always after of .nextTick and before of setInterval(, 0)
});
process.nextTick(function(){
console.log('Hello world 3'); // It's like be at the bottom at this file
});
console.log('Hello world 1');
console.log('Hello world 2');
A visual explanation as per your request:
Cases for use process.nextTick() when you have to emit and event before to handled it:
const EventEmitter = require('events');
const util = require('util');
function MyEmitter() {
EventEmitter.call(this);
// use nextTick to emit the event once a handler is assigned
process.nextTick(function () {
this.emit('event');
}.bind(this));
}
util.inherits(MyEmitter, EventEmitter);
const myEmitter = new MyEmitter();
myEmitter.on('event', function() {
console.log('an event occurred!');
});
Look at this vide where Philip Roberts give us a great explanation about runtime event loop and look at this online eventloop debugger Live test how event loop works
Source: https://github.com/nodejs/node/blob/master/doc/topics/the-event-loop-timers-and-nexttick.md#processnexttick-vs-setimmediate
Below gives you better clarity.
require
. console.log("I'm First");
setImmediate(function () {
console.log('Im setImmediate');
});
console.log("I'm Second");
process.nextTick(function () {
console.log('Im nextTick');
});
console.log("I'm Last");
/*
Output
$ node server.js
I'm First
I'm Second
I'm Last
Im nextTick
Im setImmediate
*/