Node.js setImmediate is executed before I / O callbacks (Event Loop)

Take a look at 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") }) 

When this code is executed, the following result is displayed:

enter image description here

As the Node.js documentation explains, setImmediate is executed after I / O callbacks, but in this example setImmediate is executed before I / O callbacks, am I missing something?

+5
source share
2 answers

The expected result will require the immediate return of the fs.stat methods - mainly until the end of the current event loop. But your disk will need, say, 2 ms to complete the I / O operation. Enough time to go through several cycles of events. What is happening (most likely now):

 Loop 0 starts fs.stat called fs.stat called immediate callback queued Loop 0 ends Loop 1 starts immediate callback gets called Loop 1 ends Loop 2 starts fs.stat completes, I/O callback queued fs.stat completes, I/O callback queued Loop 2 ends Loop 3 starts fs.stat I/O callback gets called fs.stat I/O callback gets called 

In fact, no one even guarantees that fs.stat 1 terminates before fs.stat2. So the result you posted could also be

 1 IMMEDIATE 2 LAST STAT 3 FIRST STAT 

What can you do:

  • You can use fs.stat sync versions. But, although it is convenient to use, it will reduce the throughput of your script, since you will block the allocation of your script during fs.stat. Therefore, if you need to run this part of the code, use one of the following methods:
  • You might want to check await "to run asynchronous code, but sequentially
  • If the completion order doesn't matter to you, you can also just use Promises to wrap both fs.stat calls. And then just do Promise.all. Or you can use async (the library), which provides many functions for working with asynchrony.
  • ...
+4
source

setImmediate NOT waiting for all I / O to complete. It just gives priority to I / O callbacks. At the time you call setImmediate , the fs.stat calls fs.stat simply not finished yet, and therefore their callbacks are not yet scheduled for the event loop.

+1
source

Source: https://habr.com/ru/post/1268810/


All Articles