手机版

解释Node.js事件循环的每个阶段

时间:2021-08-27 来源:互联网 编辑:宝哥软件园 浏览:

事件循环阶段描述图

定时器

定时器阶段在setInterval处理setTimeout回调,开始处理的时间与轮询阶段有关。

挂起的回调

在这个阶段,一些系统操作被回调,比如连接时TCP套接字接收ECONNREFUSED。

网上有一些文章称这个阶段为I/O回调,已经过时了,是错误的。具体来说,可以去Node.js官方库下的本期: #1118

闲置,准备

内部使用,忽略。

投票

轮询是一个核心阶段,等待新的I/O事件的触发,执行与I/O相关的回调。Node.js中异步的大多数情况都是I/O操作,它们的回调基本上都是在这个阶段执行的。

投票阶段主要做两件事:

计算您需要等待新的输入/输出事件的时间。当你进入轮询阶段,如果队列是空的,没有setImmediate和ready定时器,Node.js会在这里阻塞一定的时间,等待新的I/O事件到来,然后立即执行它的回调。在这种情况下,不具体块将等待多长时间,但是如果在块中某个时间之后没有新到达的输入/输出事件,则可以确定循环仍然会进入检查阶段或返回到计时器阶段。

在此阶段处理队列中的事件当进入轮询阶段时,如果队列不为空,并且没有就绪计时器,Node.js将在此处执行队列中的回调,直到队列为空或者执行的回调数量达到系统设置的某个值。然后Node.js检查是否有预设的setImmediate,如果有则进入检查阶段,否则开始检查定时器准备情况,选择返回定时器阶段或者进入检查阶段。

对于投票阶段,有些细节通过阅读官方文件并不清楚,用伪代码表示:

进入池阶段: if(已安排计时器){//官方没有提到在这种情况下会做什么} else { if(isempty(queue)){ if(has(set immediate)){//进入检查阶段} else if(!ismpty(timer)){//回到timer阶段} else {//等待新的I/O事件//新的I/O事件触发回调立即执行,执行后的逻辑不清楚}//目前看来只有setImmediate存在时才会进入检查阶段,这肯定是不合理的} if(!isEmpty(queue)) {让结果=execute(queue);If (result=='队列为空'){//官方没有谈后续逻辑//猜测是回到队列为空的处理逻辑} If (result=='达到硬限制'){//官方在这里没有解释后续逻辑//可能是和队列为空一样处理的}}}关键的疑点是从轮询阶段来看时机和目的地都不是很明确。

支票

轮询阶段执行时,会进入检查阶段,这个阶段的执行内容都是setImmediate回调。

关闭回调

套接字异常关闭,“close”事件的回调将在此阶段执行。

process.nextTick

Process.nextTick常用作异步调用,但不属于事件循环的内容。process.nextTick中的回调被放入nextTickQueue中,并在“当前操作”完成后立即处理,这与事件循环中的阶段没有联系。当前操作的最初定义是:“操作被定义为从底层C/C处理程序的转换,并处理需要执行的Javascript。”这意味着当一个JavaScript代码被执行并切换到c/c层时,将会处理nextTickQueue。

文章提到了一个特殊的情况是去重,这是Node.js内部的一个优化特性,当在计时器和检查阶段有多个回调要执行时,切换只会发生一次,所以在这种情况下,nextTick回调的执行似乎会延迟。

代码示例:

setImmediate(()={ console . log(' 1 ');process . nexttick(()=console . log(' 2 '));});setImmediate(()={ console . log(' 3 ');process . nexttick(()=console . log(' 4 '));});有两个setImmediate,进入检查阶段后,切换前需要执行setImmediate的所有回调代码,才能执行nextTick回调。所以上面代码的运行结果是“1 3 2 4”,除了上面的场景,nextTick会在setImmediate之前执行。

摘要

Node.js的Event Loop我看了两三遍,但是经常忘记,所以这次会记录下来,做个备忘录。因为知识太多容易忘记,我也发现写文章的一个好处:“有助于记忆便于复习”。

以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。谢谢你的支持。如果你想了解更多,请查看下面的相关链接

版权声明:解释Node.js事件循环的每个阶段是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。