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

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,并在任务完成时执行回调。

正确的理解:

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

你可能感兴趣的:(Node.js Event Loop 的三大常见理解误区和正确概念辨析)