setImmediate(function () {
console.log('setImmediate')
});
setTimeout(function () {
console.log('setTimeout')
}, 0);
outputs
setTimeout
setImmediate
But, these two functions inside setTimeout outputs different results.
setTimeout(function () {
setImmediate(function () {
console.log('setImmediate')
});
setTimeout(function () {
console.log('setTimeout')
}, 0);
}, 0);
Output:
setImmediate
setTimeout
As we know the event loop looks like this-
timers -> IO -> poll -> check ->close -> timers -> ...
Timers: callbacks from setInterval or setTimeout IO callbacks: callbacks from I/O events Idle: used internally by Node between IO and Poll phases Poll: retrieve new I/O events Check: callbacks from setImmediate execute here Close: handle closed connections like sockets
In the first Example -
We can see setTimeout gets executed before the setImmediate because timer queue is placed before the check Queue.
However in the second case -
When the setTimeout gets executed it triggers another setTimeout and a setImmediate, Since the Check queue is placed after the timer queue, the Check queue of the same loop executes the setImmediate but the nested setTimeout gets scheduled for the next cycle.
Which is why the code below is can also be used to run something regularly
let timerId = setTimeout(function tick() {
alert('tick');
timerId = setTimeout(tick, 2000); // (*)
}, 2000);
It schedules the next call, right at the end of the first call, which basically registers the call of setTimeout for the next loop.