EventLoop介绍

举报
小妖现世 发表于 2021/07/29 22:38:53 2021/07/29
【摘要】 Node 与浏览器 EventLoop 的差异与浏览器环境有何不同在 node 中,事件循环表现出的状态与浏览器中大致相同。不同的是 node 中有一套自己的模型。node 中事件循环的实现是依靠的 libuv 引擎。我们知道 node 选择 chrome v8 引擎作为 js 解释器,v8 引擎将 js 代码分析后去调用对应的 node api,而这些 api 最后则由 libuv 引擎驱...

Node 与浏览器 EventLoop 的差异

与浏览器环境有何不同

在 node 中,事件循环表现出的状态与浏览器中大致相同。不同的是 node 中有一套自己的模型。node 中事件循环的实现是依靠的 libuv 引擎。我们知道 node 选择 chrome v8 引擎作为 js 解释器,v8 引擎将 js 代码分析后去调用对应的 node api,而这些 api 最后则由 libuv 引擎驱动,执行对应的任务,并把不同的事件放在不同的队列中等待主线程执行。 因此实际上 node 中的事件循环存在于 libuv 引擎中。

事件循环各阶段详解

从上面这个模型中,我们可以大致分析出 node 中的事件循环的顺序:

外部输入数据-->轮询阶段(poll)-->检查阶段(check)-->关闭事件回调阶段(close callback)-->定时器检测阶段(timer)-->I/O 事件回调阶段(I/O callbacks)-->闲置阶段(idle, prepare)-->轮询阶段...

以上各阶段的名称是根据我个人理解的翻译,为了避免错误和歧义,下面解释的时候会用英文来表示这些阶段。

这些阶段大致的功能如下:

  • timers: 这个阶段执行定时器队列中的回调如  setTimeout()  和  setInterval()。
  • I/O callbacks: 这个阶段执行几乎所有的回调。但是不包括 close 事件,定时器和 setImmediate()的回调。
  • idle, prepare: 这个阶段仅在内部使用,可以不必理会。
  • poll: 等待新的 I/O 事件,node 在一些特殊情况下会阻塞在这里。
  • check: setImmediate()的回调会在这个阶段执行。
  • close callbacks: 例如 socket.on('close', ...)这种 close 事件的回调。

下面我们来按照代码第一次进入 libuv 引擎后的顺序来详细解说这些阶段:

 poll 阶段

当个 v8 引擎将 js 代码解析后传入 libuv 引擎后,循环首先进入 poll 阶段。poll 阶段的执行逻辑如下: 先查看 poll queue 中是否有事件,有任务就按先进先出的顺序依次执行回调。 当 queue 为空时,会检查是否有 setImmediate()的 callback,如果有就进入 check 阶段执行这些 callback。但同时也会检查是否有到期的 timer,如果有,就把这些到期的 timer 的 callback 按照调用顺序放到 timer queue 中,之后循环会进入 timer 阶段执行 queue 中的 callback。 这两者的顺序是不固定的,收到代码运行的环境的影响。如果两者的 queue 都是空的,那么 loop 会在 poll 阶段停留,直到有一个 i/o 事件返回,循环会进入 i/o callback 阶段并立即执行这个事件的 callback。

值得注意的是,poll 阶段在执行 poll queue 中的回调时实际上不会无限的执行下去。有两种情况 poll 阶段会终止执行 poll queue 中的下一个回调:1.所有回调执行完毕。2.执行数超过了 node 的限制。

 check 阶段

check 阶段专门用来执行 setImmediate()方法的回调,当 poll 阶段进入空闲状态,并且 setImmediate queue 中有 callback 时,事件循环进入这个阶段。

 close 阶段

当一个 socket 连接或者一个 handle 被突然关闭时(例如调用了 socket.destroy()方法),close 事件会被发送到这个阶段执行回调。否则事件会用 process.nextTick()方法发送出去。

 timer 阶段

这个阶段以先进先出的方式执行所有到期的 timer 加入 timer 队列里的 callback,一个 timer callback 指得是一个通过 setTimeout 或者 setInterval 函数设置的回调函数。

I/O callback 阶段

如上文所言,这个阶段主要执行大部分 I/O 事件的回调,包括一些为操作系统执行的回调。例如一个 TCP 连接生错误时,系统需要执行回调来获得这个错误的报告。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。