function loop() {
// Anything you want to run in a loop can be here
setImmediate(loop);
}
loop();
In this case, a setImmediate
callback is calling another setImmediate
whose callback is eventually to the queue (of the "Check" phase). Thus loop()
runs repeatedly
Does only one setImmediate
callback run per iteration of the event loop? i.e. does loop()
only run once per iteration of the event loop?
I often hear that setImmediate
is used to run a callback on the next "tick" or iteration of the event loop
However, the official Node documentation on the event loop (https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/) says:
"generally, when the event loop enters a given phase, it will perform any operations specific to that phase, then execute callbacks in that phase's queue until the queue has been exhausted or the maximum number of callbacks has executed."
This makes me think that potentially multiple setImmediate
callbacks are run per iteration of the event loop. If this is the case, how can we know how many setImmediate
callbacks are executed per "tick"?
Thanks for your help!
CodePudding user response:
Considering loop terminates for a certain condition. The setImmediate()
callback will call every time loop
's execution ends. As the doc:
setImmediate()
is designed to execute a script once the current poll phase completes.
In simple terms, its a callback for the function that you pass, which will execute for every time at the of it's execution.
Consider the following example, you will observe that in the output currentCount
value increments when the function ends or as the doc says, at every 'tick'.
const count = 5;
let currentCount = 0;
const array = [];
function loop() {
console.log('start', currentCount);
let a = setImmediate((...args) => {
if (currentCount == count) {
array.forEach((b) => clearImmediate(b));
} else {
console.log(...args, currentCount);
setTimeout(loop, 1000);
}
}, 'data');
currentCount ;
array.push(a);
console.log('end', currentCount);
}
loop();
Output:
❯ node index.js
start 0
end 1
data 1
start 1
end 2
data 2
start 2
end 3
data 3
start 3
end 4
data 4
start 4
end 5
CodePudding user response:
I believe that for the setImmediate
loop code snippet in the original question that there is only one setImmediate
callback per iteration of the event loop
I ran an example below that helped resolve this in my mind and hope this is correct:
function loop() {
console.log('setImmediate loop');
setImmediate(loop);
}
loop();
setTimeout(() => {
console.log('setTimeout');
process.exit();
}, 3); // You can adjust the timeout duration for more setImmediate callbacks before setTimeout's callback is called
# Output
setImmediate loop
setImmediate loop
setImmediate loop
setImmediate loop
setImmediate loop
setImmediate loop
setImmediate loop
setImmediate loop
setImmediate loop
setImmediate loop
setTimeout
This seems to suggest that only one (or at least not many) setImmediate
callback runs per tick of the event loop. Otherwise, if the setImmediate
loop was starving the event loop (with countless setImmediate
callbacks running per tick of the event loop), setTimeout
's callback would be blocked. I doubt that 10 callbacks is the hard limit or "maximum number of callbacks" mentioned in the official Node documentation:
"generally, when the event loop enters a given phase, it will perform any operations specific to that phase, then execute callbacks in that phase's queue until the queue has been exhausted or the maximum number of callbacks has executed."
Moreover, by adjusting the setTimeout
duration, you can vary the number of setImmediate loop
console logs before the setTimeout
callback. This confirms that a hard limit or maximum number of callbacks is not being reached
In summary, it seems that setImmediate()
's called during the "Poll" phase won't have their callbacks run until subsequent event loop ticks. In contrast, immediately resolved promises or process.nextTick()
's called while the microtask or nextTick queue is being processed will have their callbacks run before proceeding to the next stage of the event loop