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.
- ...
source share