视觉指南:理解 Node.js 事件循环中的关闭队列
原文链接:Visualizing the Close Queue in the Node.js Event Loop,2023年4月18日,by Vishwas Gopinath
欢迎来到我们关于“可视化 Node.js 事件循环”的系列文章的第七篇,也是最后一篇。在 上一篇文章 中,我们探讨了检查队列及其执行异步代码时的优先级顺序。在本文中,我们将看看事件循环中的最后一个队列——关闭队列。
入队回调函数
在我们测试本系列的最后一个实验之前,我想指出关闭队列包含与异步任务的关闭事件相关联的回调。以下是向关闭队列添加回调函数的一个示例:
readableStream.on("close", () => {
console.log("this is from readableStream close event callback");
});
注意:之前包括现在实验中处理队列的代码都采用 CommonJS 模块格式组织运行的。
实验十四
代码
// index.js
const fs = require("fs");
const readableStream = fs.createReadStream(__filename);
readableStream.close();
readableStream.on("close", () => {
console.log("this is from readableStream close event callback");
});
setImmediate(() => console.log("this is setImmediate 1"));
setTimeout(() => console.log("this is setTimeout 1"), 0);
Promise.resolve().then(() => console.log("this is Promise.resolve 1"));
process.nextTick(() => console.log("this is process.nextTick 1"));
首先,我们导入 fs
模块。然后,我们使用 fs.createReadStream()
创建一个可读流。之后,我们使用 close()
方法关闭流。我们监听 close
事件,在流关闭时发出,并添加一个侦听器来记录“this is from readableStream close event callback”。
之后都是我们熟悉的一些方法:setImmediate()
,setTimeout()
,Promise.resolve().then()
和 process.nextTick()
。
可视化
在调用栈执行所有语句后,每个队列中都会有一个回调函数,除了 I/O 队列。当没有更多的代码需要执行时,控制权进入事件循环。
首先,在 nextTick 队列中的回调出队并执行。然后,在 Promise 队列中的回调出队并执行,接着是计时器队列的回调。
接下来,事件循环移动到检查队列,其中的回调出队并执行。最后,控制权移动到关闭队列,在那里最终的回调出队并执行。
this is process.nextTick 1
this is Promise.resolve 1
this is setTimeout 1
this is setImmediate 1
this is from readableStream close event callback
译注:由于 0ms 计时器问题,上述“this is setTimeout 1”和“this is setImmediate 1”的顺序可能是颠倒的,特此说明。
推导
在事件循环的当次迭代中,所有其他队列回调执行完毕后,关闭队列回调才会执行。
总结
事件循环是一个 C 程序,用于协调 Node.js 中同步和异步代码的执行。它管理着六个不同的队列:nextTick 队列、Promise 队列、计时器队列、I/O 队列、检查队列和关闭队列。
要将任务添加到 nextTick 队列中,我们使用 process.nextTick()
方法。要将任务添加到 Promise 队列中,我们解决或拒绝一个 Promise。要将任务添加到计时器队列中,我们使用 setTimeout()
或 setInterval()
。
要将任务添加到 I/O 队列中,我们要执行一个异步方法。要将任务添加到检查队列中,我们使用 setImmediate()
函数。最后,要向关闭队列添加任务,则需要添加 close
事件监听器。
执行顺序就是我们上述描述的顺序。请注意,每个队列之间以及在定时器队列和检查队列的每个回调之间,微任务队列(nextTick 和 Promise 队列)也会被执行。
继续阅读
转载自:https://juejin.cn/post/7226193000497348664