Why Node.js setImmediate executes after I/O callba

2019-07-09 02:14发布

As new member, I'm unable to comment on topics, that's why I had to create a new topic. But in this way, I can clarify the problem, so hopefully you guys can help me.

I have read quite a lot about Node.js Event Loop. And I have shaped my understanding of it based on following materials:

Node.js Event Loop
What the heck is the event loop anyway?
Why setImmediate() execute before fs.readFile() in Nodejs Event Loop's works?

(Please feel free to suggest other materials which are informative and accurate)

Especially the third link, has given me a better understanding. But keeping that in mind, I'm unable to understand Event Loop behavior for the following code:

var fs = require('fs');
var pos = 0;

fs.stat(__filename, function() {
 console.log(++pos + " FIRST STAT");
});

fs.stat(__filename, function() {
 console.log(++pos + " LAST STAT");
});

setImmediate(function() {
 console.log(++pos + " IMMEDIATE")
})

console.log(++pos + "LOGGER");

Surprisingly, for me output is as follow:

LOGGER  
FIRST STAT  
LAST STAT  
IMMEDIATE

screenshot of my terminal, showing output as well as node version
screenshot of output from online code compiler rextester.com

Keeping the Event Loop Diagram in mind, I guess flow should be as follow:

  1. Interpretor firstly starts two stat operations.
  2. Interpreter en-queues setImmedate callback (event) in the setImmedate queue
  3. Call stack logs the logger
  4. All event queues before I/O Poll phase are empty, so Event Loop(EL) moves on
  5. In I/O Polling phase, EL collects the events and enqueues both the fs.stat callbacks in the "run completed I/O handlers" phase
  6. EL checks the Check phase, and run the setImmediate callback
  7. This round of EL ends, and second round starts
  8. In "run completed I/O handlers", EL runs both callbacks (order of them can is onn-determinstic)

Question 1: Which part of my analysis/prediction is wrong?

Question 2: At which point, does Event Loop start working? Does it start from the beginning of the app (i.e. stage 1)? or does it start once the whole code is read by interpreter, all sync tasks are done within Call Stack, and Call Stack needs more task, i.e. between stage 3-4?

Thanks in advance,

1条回答
不美不萌又怎样
2楼-- · 2019-07-09 02:33

setImmediate = execute without wait any I/O

In https://nodejs.org/docs/v8.9.3/api/timers.html#timers_setimmediate_callback_args says:

Schedules the "immediate" execution of the callback after I/O events' callbacks. Returns an Immediate for use with clearImmed

Steps:

  1. callback for First stat is queued in I/O queue
  2. callback for Last stat is queued in I/O queue
  3. callback for immediate is queued in Immediates queue
  4. LOGGER
  5. If I/O operations (in 1 and 2) are finished the callbacks in 1 and/or 2 are marked as ready to execute
  6. Execute the ready callbacks one by one (first timmer, then I/O, finally immediates). In your case:
    1. First stat
    2. Last stat
    3. LOGGER

In the case that I/O does'nt ends at 5. then LOGGER were execute before FIRST STAT and LAST STAT.

See also: https://jsblog.insiderattack.net/timers-immediates-and-process-nexttick-nodejs-event-loop-part-2-2c53fd511bb3#f3dd

查看更多
登录 后发表回答