Event Loop is a pit…

  • Author: zy445566
  • Eventloop: Node eventLoop: Node eventLoop: Node eventLoop

I recently read an article on the forums about the difference between Node and EventLoop for Chrome, and I said yes because it was written well. But not long after one of my friends said node11 was different, I said how could it be different. Then the friends posted a code, I tried to run it, slap face!

To find out

Get slapped in the face code first:

setTimeout(() => {
    console.log("timer1");
    Promise.resolve().then(function() {
        console.log("promise1");
    });
}, 0);
setTimeout(() => {
    console.log("timer2");
    Promise.resolve().then(function() {
        console.log("promise2");
    });
}, 0);
Copy the code

Those of you who know about Node eventLoop might be thinking something like this:

  • Ideally, this is the initial stage where the two setTimeouts are put into Timers.
  • Run timer1 and place the Promise of the promise1 into the timers’ next microtask queue. Similarly, run timer2. Place promise2 promises in the timers’ next stage microtask queue.
  • The microtask queues, promise1 and promise2, are not run until the timers queue is complete. So if the machine works well, this is what happens:
timer1;
timer2;
promise1;
promise2;
Copy the code

Node10 does run like this and is fine. When node11 runs, it looks like:

timer1;
promise1;
timer2;
promise2;
Copy the code

Node 11.0 = 11.0 node 11.0 = 11.0

  • Timers
    • Interval timers will be rescheduled even if previous interval threw an error. #20002
    • nextTick queue will be run after each immediate and timer. #22842

Then look at the PR of 20002 and 22842 respectively and find the following increase in #22842 in lib/timers.js:

What do these two mean?

RunNextTicks () is process._tickcallback (). Those of you who have used this will probably know that in addition to handling a few asynchronous hooks, this is where the microtask queue is executed. I added two more process._tickcallback () to the end of the setTimeout method and ran it on node10.

setTimeout(() => { console.log("timer1"); Promise.resolve().then(function() { console.log("promise1"); }); process._tickCallback(); // This line is incremented! }, 0); setTimeout(() => { console.log("timer2"); Promise.resolve().then(function() { console.log("promise2"); }); process._tickCallback(); // This line is incremented! }, 0);Copy the code

So why do it?

For greater convergence with the browser, of course.

If you know the browser’s EventLoop, you probably know that when the browser’s macro task queue executes one, it executes the microtask.

Simply put, the macro tasks of the browser can be compared to timers on Node10. Node10 executes the microtask queue only when all tasks in the timers phase queue are performed, whereas the browser executes the microtask queue only when one macro task is performed.

Node11 is now in the timer phase setTimeout,setInterval… And immediate in the check phase are both modified on Node11 to execute the microtask queue as soon as a task in a phase is executed.

The last

Therefore, it is advisable not to take advantage of node’s different features from those of the browser in a production environment. Caution is recommended even for features that are common to Node and the browser, but are not identified by the specification. Otherwise, a minor Node upgrade could result in an online incident rather than a slap in the face.

About Fundebug

Fundebug focuses on real-time BUG monitoring for JavaScript, wechat applets, wechat games, Alipay applets, React Native, Node.js and Java online applications. Since its launch on November 11, 2016, Fundebug has handled more than 1 billion error events in total, and paid customers include Google, 360, Kingsoft, Minming.com and many other brands. Welcome to try it for free!

Copyright statement

Fundebug



Blog.fundebug.com/2019/04/02/…

Are your users experiencing bugs?

Experience the Demo
Free to use