NodeJS事件循环中的轮询阶段

时间:2017-09-29 09:02:29

标签: javascript node.js event-loop

我正在通过节点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回调阶段时,为什么轮询阶段正在执行定时器和i / o的脚本?
  2. 是否轮询阶段代表定时器执行回调和i / o回调阶段和定时器和回调阶段仅用于内部处理在此阶段不执行回调?
  3. 我们可以在这个循环中放置承诺吗?之前我认为承诺可以简单地称为回调,我们可以将它们视为回调,但在this视频中,他说承诺会进入内部事件循环,但不会详细说明。
  4. 此时我很困惑。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

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

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

2)所有与I / o相关的回调和其他回调都在轮询阶段执行。待处理的回叫阶段仅适用于tcp错误之类的系统级回调,我们无需担心

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

答案 1 :(得分:1)

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

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

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

此功能块。如果未指定timeout值,它将永远阻止。

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

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

答案 2 :(得分:0)

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

希望有助于回答轮询阶段与计时器阶段的关系。从本质上讲,根据我的理解,轮询阶段可以做出决定。如有必要,再次运行计时器阶段。