likes
comments
collection
share

视觉指南:理解 Node.js 事件循环中的关闭队列

作者站长头像
站长
· 阅读数 22

原文链接:Visualizing the Close Queue in the Node.js Event Loop,2023年4月18日,by Vishwas Gopinath

视觉指南:理解 Node.js 事件循环中的关闭队列

欢迎来到我们关于“可视化 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
评论
请登录