DEV Community

Cover image for Changes to the Timers and Microtasks in Node v11.0.0 ( and above)
Deepal Jayasekara
Deepal Jayasekara

Posted on • Originally published at blog.insiderattack.net on

Changes to the Timers and Microtasks in Node v11.0.0 ( and above)

This article is a short follow up to my original article series about Node.js Event Loop. In the original article series, I discussed in detail about Timers, setImmediate, process.nextTick, Promises and many more.

However, since Node.js v11.0.0, there are some significant changes to the behavior of setTimeout, setImmediate, process.nextTick and Promises. In this article, I’m going to discuss these new changes along with some comparisons of the functionality between Node < v11.0.0 and Node ≥ v11.0.0. If you miss any of my previous articles about Node.js Event loop, I recommend you read them from the following links and return here to see the new changes introduced in Node v11.0.0.

Rationale

If you run the following piece of code in the browser and node separately, you’ll get contradicting results.

In the browser, you will get:

timeout1
timeout2
promise resolve
timeout3
timeout4
Enter fullscreen mode Exit fullscreen mode

However, in Node versions below 11.0.0, you’ll get the following output:

timeout1
timeout2
timeout3
timeout4
promise resolve
Enter fullscreen mode Exit fullscreen mode

In Node JS implementation, process.nextTick callbacks and microtasks (e.g, promise callbacks) were executed between each phase of the event loop when the C++/JavaScript boundary is crossed. Therefore, all timer callbacks are executed in the timers phase of the event loop before the Promise callback is executed which resulted in the above output.

However, this contradicting output between the browser and Node has been under discussion for a while and a feature (or a fix) has been landed in Node.js v11.0.0 to follow the browser behavior. With this feature, Node.js v11.0.0 or above will output the following which matches the browser’s output:

timeout1
timeout2
promise resolve
timeout3
timeout4
Enter fullscreen mode Exit fullscreen mode

See the following comparison between Node v10.15.1 and Node v11.10.0:

Different outputs in Node v10 and v11

This change not only affects setTimeout, but also affectssetImmediate. Let’s try to run the following code in Node v10 and Node v11 and see how the output is different.

Node v10 and Node v11 clearly give two different outputs as follows:

This behavior is quite the same if you replace Promise.resolve().then with process.nextTick because microtasks are run after the process.nextTick callbacks are run. Let’s try to run the following snippet:

The output of Node v10 and Node v11 for the above script is as follows:

What happens here?

With the new changes in Node v11, nextTick callbacks and microtasks will run between each individual setTimeout and setImmediate callbacks, even if the timers queue or the immediates queue is not empty. In terms of setTimeout and Promise callbacks, the new changes in Node v11 match the browser behavior which improves the reusability of browser JavaScript in Node.js. However, this significant change could potentially break existing Node.js applications which explicitly rely on the old behavior. Therefore, if you are upgrading to Node v11 or above (preferably the next LTS v12), you might need to consider this as important.

References:


Top comments (0)