文章目录
一、前言
JS 引擎本身不实现事件循环机制,这是由它的宿主实现的,像浏览器中的事件循环主要是由浏览器来实现的,而在 NodeJS 中,也有自己的事件循环实现,大致表现与浏览器一致,都是
- 循环 + 任务队列的流程
- 微任务优先于宏任务
当然,NodeJS 与浏览器有一些差异,并且新增了一些任务类型和任务阶段
NodeJS 也是基于 V8 引擎的,浏览器中包含的异步方法在 NodeJS 中也是一样的
nodejs 事件循环
NodeJS 的跨平台能力和事件循环机制都是基于 Libuv 库实现的
Libuv 库是事件驱动的,并且封装和统一了不同平台的 API 实现
NodeJS 中 V8 引擎将 JS 代码解析后,调用 Node API,然后 Node API 将任务交给 Libuv 去分配,最后将执行结果返回给 V8 引擎
在 Libuv 中实现了一套事件循环流程来管理这些任务的执行,所以 NodeJS 事件循环主要是在 Libuv 中完成的
1、timers 阶段
执行所有的 setTimeout()、setInterval() 的回调;
2、pending callback 阶段
执行系统操作的回调,比如 TCP 连接出错。除了 timers、setImmediate、close 的其他一切回调都在此阶段执行
3、poll 阶段
轮询等待新的连接和请求等事件,执行 I/O 回调等
该阶段是首先进入的阶段,如果这个阶段的任务队列执行完了则会进入下一个 check 阶段,执行 setImmediate 回调,如果没有 setImmediate 则会等待新的任务进来,同时还去检测 timers 的定时器有没有到期,到期会立即跳到 timers 阶段去执行 setTimeout() 和 setInterval() 的回调
4、check 阶段
setImmediate 回调执行
5、close 阶段
关闭回调执行,比如 socket.on(‘close’, …), process.on(‘close’, …)
以上 5 个阶段,每个阶段都会执行完当前阶段的任务队列,然后继续执行当前阶段的微任务队列,只有当前阶段所有微任务都执行完了才会进入到下一个阶段!!