Node.js系列:事件驱动的核心机制事件循环

❤️ 事件循环:处理异步操作的机制

目的:使Nodejs能够在单线程环境下高效运行

一、事件循环运行机制:依赖libuv库

事件循环机制是基于libuv库(一个多平台的异步I/O的库)构建的;

libuv为Nodejs提供了高效的事件驱动的I/O操作能力,libuv负责在底层进行实际的操作调度 ,当这些操作完成时,通过事件循环将对应的回调函数 在合适的阶段进行调用;事件循环依赖kibuv实现高效的异步操作

比如在定时器管理方面,libuv 提供了精准的定时器机制,让事件循环能够准确地在合适的时间执行定时器回调函数(像setTimeoutsetInterval相关的回调)。

在非阻塞 I/O 操作上,事件循环借助 libuv 可以在等待 I/O 完成的同时处理其他事务,避免了线程的大量阻塞,提高了程序的整体性能。

二、事件循环的6个阶段:每个阶段都对应一个任务队列

当事件循环进入某个阶段时, 将会在该阶段内执行回调,直到队列耗尽或者回调的最大数量已执行, 那么将进入下一个处理阶段

1. 定时器Timers阶段 :执行setTimeout 和setInterval的回调函数

当设定的时间到达后,回调函数会被添加到 定时器阶段的任务队列中。(定时任务不一定按照设定的时间执行)

2.I/O回调阶段 :主要用于处理各种I/O操作(如文件读取,网络请求等)完成后的回调函数

当一个I/O操作完成后, 其对应的回到函数就会被添加到这个任务队列中; 比如fs.readFile,文件读取完成后的回调函数就会在这个阶段会执行

3.闲置阶段:这是一个内部使用的过渡阶段

  • 主要用于一些内部操作和准备工作,一般开发者很少直接涉及这个阶段的具体操作

4.轮询(Poll)阶段 :事件循环的关键,主要有两个功能

  • 等待新I/O事件到来
  • 处理定时器到期后的任务(如果定时器阶段没来得及处理)

如果没有新的I/O事件并且定时器也没有到期任务,这个阶段会阻塞等待

5.检查(check)阶段:主要用于执行setImmediate的回调函数

  • 在当前轮询阶段结束后立即执行

6.关闭事件回调阶段:TPC服务器对象关闭时,对应的关闭回调函数

  • 例如关闭一个服务器套接字段后,用于清理资源等的关闭回调函数会在这个阶段被调用;
    • 如:socket.on('close', ...)

三、任务队列和执行顺序

微任务:

  • process.nextTick: 会在当前操作完成后立即执行,在微任务之前执行
  • promise.then
  • queueMicrotask():是标准的微任务

宏任务:

  • setTimeout、setInterval
  • IO事件
  • 检查阶段的setImmediate
  • 关闭事件

执行顺序:

  • nextTick microtask queue
  • other microtask queue
  • timer queue
  • poll queue
  • check queue
  • close queue

微任务会在当前执行栈为空的时候立即执行,宏任务会根据事件循环的阶段顺序来执行

其他:

queueMicrotask 与 process.nextTick 的区别?

  • process.nextTick 会在当前操作完成后立即执行,甚至在事件循环的下一个阶段开始之前,而且在微任务之前执行。
  • queueMicrotask 是标准的微任务,会在当前事件循环的微任务队列中等待,在当前执行上下文的同步代码和 process.nextTick 之后,但在宏任务之前执行。

setTimeoutsetImmediate的输出顺序

  • 遇到setTimeout,虽然设置的是0毫秒触发,但实际上会被强制改成1ms,时间到了然后塞入times阶段;
  • 先进入times阶段,检查当前时间过去了1毫秒没有,如果过了1毫秒,满足setTimeout条件,执行回调,如果没过1毫秒,跳过
  • 跳过空的阶段,进入check阶段,执行setImmediate回调

这里的关键在于这1ms,如果同步代码执行时间较长,进入Event Loop的时候1毫秒已经过了,setTimeout先执行,如果1毫秒还没到,就先执行了setImmediate

相关推荐
神仙别闹10 小时前
基于VUE+Node.JS实现(Web)学生组队网站
前端·vue.js·node.js
BXCQ_xuan11 小时前
基于Node.js的健身会员管理系统的后端开发实践
后端·mysql·node.js
wt_cs11 小时前
身份证实名认证接口数字时代的信任基石-node.js实名认证集成
开发语言·node.js·php
李剑一13 小时前
写一个vitepress新建文章脚本,自动化创建链接,别再手写了!
前端·node.js·vitepress
名字越长技术越强1 天前
Node.js学习
学习·node.js
知识分享小能手1 天前
JavaScript学习教程,从入门到精通,Ajax与Node.js Web服务器开发全面指南(24)
开发语言·前端·javascript·学习·ajax·node.js·html5
dwqqw1 天前
opencv图像库编程
前端·webpack·node.js
layman05281 天前
node.js 实战——(fs模块 知识点学习)
javascript·node.js
本本啊1 天前
node 启动本地应用程序并设置窗口大小和屏幕显示位置
前端·node.js
全栈派森2 天前
Next15 + Prisma + Auth5 实战讲解
react.js·node.js·next.js