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

相关推荐
之歆7 小时前
Node.js 与 NPM 包管理完全指南
前端·npm·node.js
12点一刻8 小时前
npx 使用入门教程:是什么、怎么用、和 npm 有什么区别
前端·npm·node.js
Sca_杰8 小时前
速通抖音开放平台API-生活服务商应用
javascript·node.js
console.log('npc')9 小时前
核心实战篇 生成式 UI+A2UI 协议 + 全栈 Agent 项目落地
node.js·react·#生成式ui·a2ui协议·ui agent·ai前端实战
Rain5099 小时前
1.3. Next.js与Nest.js在AI数据分析中的角色
前端·javascript·人工智能·后端·数据分析·node.js·ai编程
向上的车轮9 小时前
TypeORM 1.0 正式发布:新一代 Node.js ORM 框架全面解析
typescript·node.js·typeorm
晚风叙10 小时前
使用Gemini快速修复Node.js 代码报错
node.js
之歆11 小时前
Node.js HTTP 模块深度解析与实战指南
网络协议·http·node.js
带娃的IT创业者11 小时前
深度解析 Bun:重新定义 JavaScript 运行时的性能边界
开发语言·javascript·node.js·ecmascript·bun·运行时
AIFQuant12 小时前
全球行情自动更新、多品种展示、性能优化实战指南
python·性能优化·金融·node.js·restful