Node.js Event Loop 的三大常见理解误区和正确概念辨析

举报
Jerry Wang 发表于 2023/01/31 09:59:14 2023/01/31
【摘要】 Node.js Event loop 监控器。高的 frequency 和低的持续时间是最理想的 event loop 状态。上图显示三点半到五点半之间,event loop 的 frequency 骤降,然后 duration 居高不下。Node.js 是一个基于事件的平台。 这意味着在 Node 中发生的一切都是对事件的反应。通过 Node 的事务会遍历级联的回调(a cascade o...

Node.js Event loop 监控器。高的 frequency 和低的持续时间是最理想的 event loop 状态。

上图显示三点半到五点半之间,event loop 的 frequency 骤降,然后 duration 居高不下。

Node.js 是一个基于事件的平台。 这意味着在 Node 中发生的一切都是对事件的反应。通过 Node 的事务会遍历级联的回调(a cascade of callbacks)。

这一切都由一个名为 libuv 的库处理,它提供了一种称为事件循环的机制。

关于 Node.js 的事件循环,有很多误解。

误解1:事件循环机制运行在独立于用户逻辑的单独线程内

误解:

有一个主线程,用户的 JavaScript 代码(userland 代码)在其中运行,另一个主线程运行事件循环。 每次发生异步操作时,主线程都会将工作交给事件循环线程,一旦完成,事件循环线程就会通知主线程执行回调。

正确的理解:

只有一个线程执行 JavaScript 代码,这是运行事件循环的线程。 回调的执行(运行中的 Node.js 应用程序中的每个用户空间代码都是回调)由事件循环完成。

误解2:异步操作通过线程池完成

异步操作,如使用文件系统、执行出站 HTTP 请求或与数据库对话,总是加载到 libuv 提供的线程池中。

正确的理解:

Libuv 默认创建一个包含四个线程的线程池来卸载异步工作。 今天的操作系统已经为许多 I/O 任务提供了异步接口(例如 Linux 上的 AIO)。
只要有可能,libuv 就会使用那些异步接口,避免使用线程池。

这同样适用于第三方子系统,如数据库。 这里驱动程序的作者宁愿使用异步接口也不愿使用线程池。

简而言之:只有在没有其他办法的情况下,才会使用线程池进行异步I/O.

误解3:Event Loop 利用了栈或者队列的数据结构

事件循环不断遍历异步任务的 FIFO,并在任务完成时执行回调。

正确的理解:

虽然涉及到类似队列的结构,但事件循环不会遍历并处理堆栈。 作为一个进程的事件循环是一组具有特定任务的阶段,这些阶段以循环方式处理。

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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