问题描述
// * Run this snippet of code multiple times
const fs = require('fs');
setTimeout(() => {
console.log('timer');
});
fs.readFile('','utf-8',(err,data) => {
console.log('io');
});
setImmediate(() => {
console.log('check');
});
结果 1
有时我得到timer
io
check
结果 2
和其他时间。我要io
check
timer
谁能解释一下这里发生了什么?我期待结果 1。
解决方法
这与事件循环如何在不止一件事情可用时选择要做的事情有关。 Here 你可以找到一个很好的解释。
如果您确实想设置该顺序,请尝试在 setTimeout() 回调中使用 async/await
或调用 fs.readFile()
。
根据 node.js 事件循环文档,调用 setTimeout 设置等待函数执行的最短时间。接下来开始异步文件读取。然后事件循环的轮询阶段将开始。轮询阶段有一个回调函数队列需要完成。如果文件读取未完成,其回调函数(console.log)将不会放入轮询队列。轮询阶段将改为等待计时器满足最小阈值时间,然后循环回到计时器回调执行阶段。由于您的 setTimeout 设置为零毫秒,轮询阶段通常会先退出并完成计时器回调 (console.log),然后返回轮询以完成读取的文件。这就是为什么有时如果您的底层操作系统延迟文件读取,您的 setTimeout 首先完成,或者如果操作系统延迟 setTimeout,文件读取首先完成。 setImmediate 总是会在轮询 (io) 阶段之后立即发生。