Node.js setImmediate在I / Ocallback之前执行(Event Loop)

看看下面的代码:

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") }) 

当我执行这个代码时,显示以下结果:

在这里输入图像描述

正如Node.js 文档所解释的,setImmediate是在I / Ocallback之后执行的,但在本例中,在I / Ocallback之前正在执行setImmediate,我错过了什么?

您期待的结果将需要fs.stat方法立即返回 – 基本上在当前事件循环结束之前。 但是,您的磁盘需要2ms才能完成I / O操作。 足够的时间来运行相当多的事件循环。 发生什么(最可能是)现在是:

 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 

其实没有人保证fs.stat 1在fs.stat2之前完成。 所以你发布的结果也可以

 1 IMMEDIATE 2 LAST STAT 3 FIRST STAT 

你可以做什么:

  1. 您可以使用fs.stat的同步版本。 但是,尽pipe使用起来很舒服,但会降低脚本的吞吐量,因为在fs.stat运行的时候您将阻止脚本的执行。 所以如果你不得不经常运行这部分代码,请使用以下方法之一!
  2. 您可能需要检查“ await ”以asynchronous运行代码,但要按顺序运行
  3. 如果完成顺序对您无关紧要,您也可以简单地使用Promise来包装这两个fs.stat调用。 然后就做一个Promise.all。 或者你可以使用asynchronous(一个库),提供了许多function来处理asynchronous性

setImmediate不会等待所有IO操作完成。 它只是优先考虑IO callback 。 当你在这里调用setImmediatefs.stat调用还没有完成,因此它们的callbackfs.stat还没有安排在事件循环中。