Home > Back-end >  In Node.js, setImmediate() callbacks get executed on current event loop tick, or on the next one?
In Node.js, setImmediate() callbacks get executed on current event loop tick, or on the next one?

Time:10-21

In the official docs, "setImmediate() vs setTimeout()" section, it says: "setImmediate() is designed to execute a script once the current poll phase completes", and as i understand, it means also current tick/event loop cycle.

However later in the "process.nextTick() vs setImmediate()" section, it says: "setImmediate() fires on the following iteration or 'tick' of the event loop".

So which one is the correct answer, did i miss anything here?

Thanks in advance.

Docs relevant page: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

CodePudding user response:

Thanks for joining Stack Overflow!, Your question is excellent I must say!


As you can see by the image below: Event loop Circle

The diagram is from Event Loop and the Big Picture — NodeJS Event Loop Part 1 By Deepal Jayasekara

"The boxes around the circle illustrate the queues of the different phases we seen before, and the two boxes in the middle illustrate two special queues that need to be exhausted before moving from one phase to the other. The “next tick queue” processes callbacks registered via nextTick(), ..."

From Synk - Node.js Event-Loop: How even quick Node.js async functions can block the Event-Loop, starve I/O which reference the article above


So the difference between setTimeout, setImmediate and nextTick is:

  • setTimeout schedules a script to be run after a minimum threshold in ms has elapsed.1
  • setImmediate runs after the poll phase (the pool phase is the IO events queue in the diagram)
  • nextTick runs between phases.

1 The order in which the timers are executed will vary depending on the context in which they are called., see here for more

CodePudding user response:

Simple answer:

setImmediate runs on the next tick.

Details:

setImmediate and setTimeout both run in different phases on the event loop.

That is why when setTimeout is set with zero delay it will not run immediately. Use setImmediate which always run on the next tick of the event loop.

but

process.nextTick basically does not care about phases of event loop. The callback you assign to this method will get executed after the current operation is complete and before event loop continues.

The document you linked has a very good explanation about the differences. I'll just grab your attention to few points here. In setimmediate-vs-settimeout the order of call is nondeterministic UNLESS they are scheduled within an I/O cycle like below example.

Now add the process.nextTick to the example

const fs = require('fs');
//  I/O cycle
fs.readFile(__filename, () => {
  setTimeout(() => {
    console.log('timeout');
  }, 0);
  setImmediate(() => {
    console.log('immediate');
  });
});

process.nextTick(() => {
  console.log('nextTick')
})

Output:

nextTick
immediate
timeout

If you run the above code whatever is in process.nextTick function will get executed first. The reason is, it runs before event loop continues. Remember, both setTimeout and setImmediate are event loop related but not process.nextTick.

Be very careful how you use the process.nextTick. You can end up in bad situations if you are not using it properly.

  • Related