Node\.js 事件循环核心知识点总结
Node.js 事件循环核心知识点总结
一、核心概述
Node.js 基于单线程、非阻塞、异步 I/O模型运行,**事件循环(Event Loop)**是其实现异步调度的核心,负责统筹所有异步任务的执行顺序,避免线程阻塞,实现高并发能力。
事件循环会按固定阶段循环执行,每个阶段拥有独立回调队列,清空当前阶段队列后,才会进入下一阶段,且每个阶段切换前会优先清空所有微任务。
二、事件循环完整执行阶段(从上至下为执行顺序)
完整6阶段顺序:timers → pending callbacks → idle/prepare → poll → check → close callbacks
1. Timers 阶段(定时器阶段)
-
执行任务:
setTimeout\(\)、setInterval\(\)回调函数 -
核心特点:设定的时间为最小延迟,非精确执行时间,需等待当前阶段空闲后执行
2. Pending callbacks 阶段(延迟回调阶段)
-
执行任务:上一轮循环遗留的 I/O 错误回调、系统级回调
-
核心特点:Node 内部底层处理,日常业务开发无需关注
3. Idle/Prepare 阶段(空闲预备阶段)
- 核心特点:仅 Node 内部调度使用,开发者无业务交互
4. Poll 阶段(轮询阶段,核心重点)
-
执行任务:普通文件、网络等** I/O 异步回调**
-
核心逻辑:
-
队列有任务:同步清空当前所有 I/O 回调
-
队列为空:若存在
setImmediate,直接进入 Check 阶段;若有定时器到期,回到 Timers 阶段;无任务则阻塞等待新事件
-
5. Check 阶段(检查阶段)
-
执行任务:专属执行
setImmediate\(\)回调 -
核心特点:Poll 阶段结束后立即执行,优先级高于定时器(特定场景)
6. Close callbacks 阶段(关闭回调阶段)
-
执行任务:关闭类回调,如
socket\.close\(\)、stream\.on\(\&\#39;close\&\#39;\) -
核心特点:一轮循环的收尾阶段,处理资源释放回调
三、任务分类与执行优先级
Node 异步任务分为 微任务(高优先级) 和 宏任务(低优先级),微任务执行优先级高于所有宏任务。
1. 微任务队列(优先执行)
优先级:process\.nextTick > 原生 Promise.then/catch/finally
-
process\.nextTick:Node 独有微任务,全局最高异步优先级 -
Promise 微任务:常规异步微任务,优先级次于 nextTick
-
规则:每一个事件循环阶段切换前,必须清空所有微任务
2. 宏任务队列(按阶段执行)
执行顺序对应事件循环阶段:Timers 宏任务 → Poll I/O 宏任务 → Check 宏任务 → Close 宏任务
-
Timers 宏任务:
setTimeout、setInterval -
Poll 宏任务:普通文件、网络 I/O 回调
-
Check 宏任务:
setImmediate
3. 终极执行顺序(必记)
同步代码 > process.nextTick > Promise 微任务 > setTimeout/setInterval > setImmediate
四、重点 API 特殊场景
setTimeout(0) vs setImmediate 区别
-
全局主代码中:执行结果随机,取决于 Node 进程启动耗时,启动快则定时器先执行,反之 setImmediate 先执行
-
I/O 回调内部:setImmediate 必定优先执行(I/O 回调属于 Poll 阶段,结束后直接进入 Check 阶段,跳过 Timers 阶段)
五、经典代码示例与执行解析
示例代码
console.log('同步代码1');
setTimeout(() => {
console.log('setTimeout 0ms');
}, 0);
setImmediate(() => {
console.log('setImmediate');
});
Promise.resolve().then(() => {
console.log('Promise.then 微任务');
});
process.nextTick(() => {
console.log('process.nextTick');
});
console.log('同步代码2');
执行输出结果
同步代码1
同步代码2
process.nextTick
Promise.then 微任务
setTimeout 0ms
setImmediate
执行步骤拆解
-
执行所有同步代码,打印同步内容
-
清空微任务队列:优先执行
process\.nextTick,再执行 Promise 微任务 -
进入事件循环:Timers 阶段执行 setTimeout 回调
-
流转到 Check 阶段,执行 setImmediate 回调
六、核心总结
-
事件循环核心阶段:Timers、Poll、Check 为业务核心阶段,其余为底层内部阶段
-
微任务优先级永远高于宏任务,nextTick 是最高优先级异步任务
-
定时器是最小延迟,非精准定时,受事件循环调度影响
-
I/O 回调中 setImmediate 永远快于 0ms 定时器
本文由萧兮的博客原创发布,欢迎转载,转载务必保留原文链接。
萧兮的博客:https://www.20010515.xyz · 原文:https://www.20010515.xyz/posts/019e4ece-afe7-7cb0-a98b-a32478890169