我正在通过节点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回调阶段,然后轮询阶段完成的工作是什么。它还说线程可能在民意调查阶段睡觉,但我不能正确使用它 我的问题是 -
此时我很困惑。任何帮助将不胜感激。
答案 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。
希望有助于回答轮询阶段与计时器阶段的关系。从本质上讲,根据我的理解,轮询阶段可以做出决定。如有必要,再次运行计时器阶段。