首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >节点的事件循环阶段回调

节点的事件循环阶段回调
EN

Stack Overflow用户
提问于 2020-04-11 19:52:35
回答 1查看 572关注 0票数 2

我读到了节点的事件循环阶段,并说

  • 定时器:这个阶段执行setTimeout()和setInterval()计划的回调。
  • 挂起回调:执行延迟到下一个循环迭代的I/O回调。
  • 闲置,准备:只在内部使用。
  • 轮询:检索新的I/O事件;执行与I/O相关的回调(除了close回调(计时器调度的回调和setImmediate())外,几乎所有回调除外);节点将在适当的时候阻塞在这里。
  • check:在这里调用setImmediate()回调。
  • 关闭回调:一些关闭回调,例如socket.on(“关闭”,.)。

所以这里我有一个简单的代码来测试上面的一些阶段。当您执行代码时,您将得到以下输出:

  1. 即时
  2. 超时

但是套接字回调(如doc )是最后一个阶段。为什么要先执行?

代码语言:javascript
复制
let socket = require("net").createServer();

socket.on("data", function (data) {
  console.log(data.toString());
});

socket.on("close", function (data) {
  console.log("close");
});

socket.listen(8080);

const fs = require("fs");

fs.readFile("readme.txt", () => {
  socket.close();
  setTimeout(() => {
    console.log("timeout");
  }, 0);

  setImmediate(() => {
    console.log("immediate");
  });
});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-11 20:31:19

首先,请记住,本地关闭套接字触发的close事件不是网络操作。它不是由传入的网络事件触发的。它是由本地套接字实现触发的,该实现决定何时触发关闭事件,以通知监视本地套接字的其他任何人它现在已关闭。它甚至可以同步触发(如果实现它的net库选择这样做)。因此,您所读到的任何关于如何在事件循环中对网络事件进行排序或排序的内容都不适用于这里。此事件不是由传入的网络操作触发的,也不像传入的网络操作那样通过事件循环。

我在调试器中遍历了您的代码,并深入到socket.close()中,试图查看实现做了什么。它到达这一行这里,其中is调用this._handle.close()。这将进入用C++编写的一些TCP包装层,调试器将不让您进一步跟踪它。

然后,该函数继续调用emitCloseIfDrained(),后者调用defaultTriggerAsyncIdScope(),并将process.nextTick()作为异步机制使用。

因此,本地调用socket.close()似乎会导致套接字库在调用close事件之前使用process.nextTick(),这将使其在其他事情之前得到处理具有相当高的优先级,但将在事件循环的未来滴答中进行处理。

但是,我希望您现在可以看到这是如何依赖于超级实现(取决于在任何库中触发事件的方式),而不是文档化的,因此不应该依赖于您的实现。出于对知识的好奇,想尽可能多地理解这一点是可以的,但您不应该设计依赖于这种实现细节级别的代码。一个特殊的特性,比如当close事件在套接字上触发时,没有文档记录,也没有承诺它将来不会改变。如果您的代码需要对异步事件进行特定的排序,则需要编写代码来管理该序列,以确保无论实现细节的级别如何,都会发生这种情况。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61162869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档