【问题标题】:Poll phase in NodeJS event loopNodeJS 事件循环中的轮询阶段
【发布时间】:2018-03-11 03:45:07
【问题描述】:

我正在通过节点docs 进行事件循环,我很困惑。 它说-

timers: this phase executes callbacks scheduled by setTimeout() and 
setInterval().
I/O callbacks: executes almost all callbacks with the exception of close callbacks, the ones scheduled by timers, and setImmediate().
idle, prepare: only used internally.
poll: retrieve new I/O events; node will block here when appropriate.
check: setImmediate() callbacks are invoked here.
close callbacks: e.g. socket.on('close', ...).

然后在详细的轮询阶段,他们说它执行定时器调度的定时器,并处理轮询队列中的 i/o 事件。我的困惑是我们已经有这些回调的计时器阶段和 i/o 回调阶段,那么轮询阶段所做的工作是什么。它还说线程可能在轮询阶段休眠,但我没有正确理解。
我的问题是-

  1. 当我们已经有了定时器和 i/o 回调阶段时,为什么 poll 阶段正在执行定时器和 i/o 的脚本?
  2. 是否像 poll 阶段代表计时器和 i/o 回调阶段执行回调,而计时器和回调阶段仅用于内部处理,在此阶段不执行回调?
  3. 在这个循环中我们可以在哪里放置 Promise?之前我认为可以将 promise 简单地视为回调,我们可以将它们视为回调,但在 this 视频中,他说 promise 进入内部事件循环,但没有详细讨论。

此时我很困惑。任何帮助将不胜感激。

【问题讨论】:

    标签: javascript node.js event-loop


    【解决方案1】:

    我自己也只是在阅读。就计时器而言,关于事件循环的documentation 以示例的形式给出了一个不错的答案。假设 setTimeout 计时器设置为在 100 毫秒后触发,但 I/O 进程正在进行中(在轮询阶段)并且需要超过 100 毫秒才能执行,例如 150 毫秒。一旦完成,轮询阶段将返回计时器阶段,并在预期的 100 毫秒之后执行 setTimeout,即 150 毫秒。

    希望有助于回答轮询阶段与计时器阶段的关系。本质上,据我了解,轮询阶段可以“决定”在必要时再次运行计时器阶段。

    【讨论】:

    【解决方案2】:

    Nodejs 有 5 个主要阶段。
    1) 定时器阶段。
    2) 等待回调阶段。
    3) 轮询阶段
    4) 检查(立即设置)。
    5) 关闭

    回答您的问题。
    1)定时器和检查阶段的回调在各自的阶段执行,而不是在轮询阶段执行。

    2)所有I/O相关的回调和其他都在轮询阶段执行。待处理的回调阶段仅针对系统级回调,例如 tcp 错误,我们不关心

    3) 在每个阶段之后,node js 都有一个内部事件循环来解决所有 process.nextTick 回调,以及另一个较小的事件循环,它执行已解决的 Promise 然后回调,即 Promise.resolve.then() 回调。

    【讨论】:

    • "2)所有I/O相关的回调等都在轮询阶段执行。" - 你指的这里的“其他”是什么?
    【解决方案3】:

    poll 阶段归结为异步 I/O 等待。 Libuv 将根据操作系统使用不同的 API,但它们通常具有相同的模式。我将以select() 为例。

    poll 基本上是这样的系统调用:

    select(maxNumberOfIO, readableIOList, writableIOList, errorIOList, timeout);
    

    此功能阻塞。如果没有指定 timeout 值,它会永远阻塞。

    结果是只要没有 I/O 活动,node.js 将无法执行任何 javascript。这显然使得不可能执行像setTimeout()setInterval() 这样的基于时间的回调。

    因此,节点在调用这样的函数之前需要做的就是计算出要作为timeout传递的值。它通常通过遍历所有计时器的列表并找出它可以等待 I/O(下一个最近的计时器)的最短时间并将其用作超时值来做到这一点。它基本上处理所有计时器,但不执行它们的回调,它会计算等待时间。

    【讨论】:

    猜你喜欢
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 2021-10-07
    • 1970-01-01
    • 2012-01-29
    • 2015-08-13
    相关资源
    最近更新 更多