Node.js事件循环

135 阅读2分钟

我们是基于Node.js10+版本进行事件循环的讲解,这里要注意一个概念,Node.js的事件循环和浏览器的事件循环是不一样的。

浏览器的事件循环的核心是宏任务和微任务,而Node.js还有阶段性任务执行阶段。下面我们来详细了解一下。

事件循环通俗来说就是一个无限的 while 循环。Node.js的事件循环主要包括6个阶段

(1)timers:本阶段执行已经被 setTimeout() 和 setInterval() 调度的回调函数,简单理解就是由这两个函数启动的回调函数。

(2)pending callbacks:本阶段执行某些系统操作(如 TCP 错误类型)的回调函数。

(3)idle、prepare:仅系统内部使用,你只需要知道有这 2 个阶段就可以。

(4)poll:检索新的 I/O 事件,执行与 I/O 相关的回调,其他情况 Node.js 将在适当的时候在此阻塞。这也是最复杂的一个阶段,所有的事件循环以及回调处理都在这个阶段执行,接下来会详细分析这个过程。

(5)check:setImmediate() 回调函数在这里执行,setImmediate 并不是立马执行,而是当事件循环 poll 中没有新的事件处理时就执行该部分。

(6)close callbacks:执行一些关闭的回调函数,如 socket.on('close', ...)。

有几个关键点我们需要解释一下

运行起点

Node.js 进程启动后,就发起了一个新的事件循环,也就是事件循环的起点。

Node.js 事件循环

事件循环的主要包含微任务和宏任务。

微任务:在 Node.js 中微任务包含 2 种——process.nextTick 和 Promise。微任务在事件循环中优先级是最高的,因此在同一个事件循环中有其他任务存在时,优先执行微任务队列。并且process.nextTick 和 Promise 也存在优先级,process.nextTick 高于 Promise。

宏任务:在 Node.js 中宏任务包含 4 种——setTimeout、setInterval、setImmediate 和 I/O。宏任务在微任务执行之后执行,因此在同一个事件循环周期内,如果既存在微任务队列又存在宏任务队列,那么优先将微任务队列清空,再执行宏任务队列。这也解释了我们前面提到的第 3 个问题,事件循环中的事件类型是存在优先级。

以上我们主要介绍了浏览器和Node.js的事件循环的不同,并且简单分析了一下Node.js的事件循环的几个阶段介绍了一下事件循环的主要构成。

此文章为6月Day015学习笔记,内容来源于极客时间《Node.js开发实战》,强烈推荐该课程!