【问题标题】:in Node.js event loop - will callbacks to say i/o events say 'new HTTP request received' be executed in the 'I/O Callbacks' phase OR 'Poll' phase在 Node.js 事件循环中 - 是否会在“I/O 回调”阶段或“轮询”阶段执行说 i/o 事件说“收到新 HTTP 请求”的回调
【发布时间】:2017-04-15 14:46:33
【问题描述】:

我看到事件循环通常在每次迭代中通过以下循环:计时器 -> I/O 回调 -> 空闲 -> 轮询 -> 检查 -> 关闭 根据官方 Node.js 文档 https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

现在它还说“I/O 回调”阶段为某些系统操作(例如 TCP 错误类型)执行回调,例如 TCP 连接错误等典型操作。

在“轮询”阶段 - 它说“检索新的 I/O 事件”。比如传入的连接、数据等

我很困惑。在哪个阶段执行 I/O 事件(回调处理程序),如“收到新的 HTTP 请求”、“从数据库接收的每个先前查询的数据”?

【问题讨论】:

  • 请注意,从普通用户的角度来看 - 这通常不应该让您非常关心 :)

标签: node.js event-loop


【解决方案1】:

一般

通常,您不应该关心这些阶段。即使是微任务(如 nextTick)和宏任务(如 setImmediate)之间的区别对于每天的 NodeJS 开发人员来说也不是很重要。那篇文章深入探讨了 Node 如何在内部处理事情。

用户通常需要关心的是,当他们注册请求时 - 他们提供的回调最终将在将来的某个时间被调用,即通常足够快,只要它们不会通过在 Node 进程上执行大量同步 CPU 绑定工作来“阻塞事件循环”。

您的具体问题

在哪个阶段执行 I/O 事件(回调处理程序),例如“收到新的 HTTP 请求”、“从数据库接收到的每个先前查询的数据”?

它们在轮询阶段执行:

如果轮询队列不为空,则事件循环将遍历其回调队列,同步执行它们,直到队列耗尽或达到系统相关的硬限制。

请注意,轮询阶段并不是唯一可能执行 I/O 回调的地方。 (有点不好命名的)I/O callbacks 阶段也负责一些回调。这是由于 libuv 的工作原理,并且在您的代码中应该是透明的。此外 - 一些库(如 DB 库)可能会在计时器内(在计时器阶段)进行自己的调度和运行回调代码 - 并且一些异步回调(如关闭回调)在它们自己的阶段运行。

【讨论】:

  • 没有。这是错误的。它们不在轮询阶段执行。轮询阶段实际上是阻塞的,直到操作系统向解释器发送事件。它们在回调阶段执行。在 OP 的问题中,node.js 文档似乎将回调阶段分为两部分,即计时器阶段和 I/O 回调阶段。这只是为了澄清计时器在其他回调之前处理。
  • 你给if the poll queue is not empty的描述是回调阶段。
【解决方案2】:

没有什么可混淆的。所有异步回调都在回调阶段执行。它是解释器执行 javascript 的仅有的两个地方之一:脚本启动时和回调阶段。

【讨论】:

  • 我认为这根本不能回答 OP 的问题 - 有超过 2 个阶段。
  • 如果你不是Node.js的实现者,至少你应该仔细阅读文档,从nodejs.org/en/docs/guides/event-loop-timers-and-nexttick,我可以看到它是'poll phase'
  • @Guigui 仔细阅读文档。在轮询阶段,如果轮询队列不为空,则表示回调阶段。更具体地说,阅读代码,而不仅仅是文档。代码无法在轮询阶段执行,因为在轮询阶段进程处于休眠状态(在操作系统用事件中断我们之前什么都不执行)
猜你喜欢
  • 2017-11-15
  • 1970-01-01
  • 2018-03-11
  • 2020-06-17
  • 1970-01-01
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 2016-11-18
相关资源
最近更新 更多