当前位置: 首页 > news >正文

事件循环(Event Loop)机制对比:Node.js vs 浏览器​

​1. 共同点:基本事件循环模型​

两者都基于 ​​"任务队列 + 循环处理"​​ 的机制:

  • ​主线程​​执行同步代码。
  • ​异步任务​​(如I/O、定时器)完成后,回调函数被放入任务队列。
  • ​事件循环​​不断检查队列,按规则取出任务执行。

​2. 核心区别​

​(1)任务队列类型不同​
​浏览器​​Node.js​
​宏任务(Macrotask)​​:
• script(整体代码)
• setTimeout/setInterval
• DOM事件回调(如点击)
• requestAnimationFrame
​宏任务(Timers/Poll/Check)​​:
• setTimeout/setInterval(Timers)
• I/O回调(Poll)
• setImmediate(Check)
​微任务(Microtask)​​:
• Promise.then/catch/finally
• MutationObserver
• queueMicrotask
​微任务(Microtask)​​:
• Promise.then/catch/finally
• process.nextTick(优先级最高)

​(2)执行顺序差异​

​浏览器的循环流程​​:

  1. 执行 ​​一个宏任务​​(如 script)。
  2. 清空 ​​所有微任务队列​​。
  3. 渲染页面(如有需要)。
  4. 重复上述步骤。

​Node.js 的循环阶段​​(分6个阶段):

  1. ​Timers​​:执行 setTimeout/setInterval 回调。
  2. ​Pending I/O​​:处理系统操作(如TCP错误)。
  3. ​Idle/Prepare​​:内部使用(可忽略)。
  4. ​Poll​​:
    • 执行I/O回调(如文件读取)。
    • 如果队列为空,会等待新I/O事件或检查Timers。
  5. ​Check​​:执行 setImmediate 回调。
  6. ​Close​​:处理关闭事件(如 socket.on('close'))。

​每次阶段切换前​​:

  • 先清空 process.nextTick 队列(优先级最高)。
  • 再清空微任务队列(如 Promise)。

​3. 关键差异点​

​特性​​浏览器​​Node.js​
​微任务优先级​Promise 和 MutationObserver 同级process.nextTick > Promise
​定时器精度​受页面渲染影响(最小4ms)更高精度(依赖系统时钟)
​特有API​requestAnimationFramesetImmediateprocess.nextTick
​I/O处理阶段​无明确阶段集中在 ​​Poll 阶段​

​4. 代码示例对比​

​浏览器:​

setTimeout(() => console.log('宏任务1'), 0); Promise.resolve().then(() => console.log('微任务1')); // 输出顺序:微任务1 → 宏任务1

​Node.js:​

setTimeout(() => console.log('Timers阶段'), 0); setImmediate(() => console.log('Check阶段')); process.nextTick(() => console.log('nextTick')); Promise.resolve().then(() => console.log('Promise微任务')); // 可能输出顺序: // nextTick → Promise微任务 → Timers阶段 → Check阶段


​5. 总结口诀​

​浏览器:​
宏微交替,渲染插队,RAF动画优先。

​Node.js:​
六阶段转,nextTick先,Poll等I/O,Immediate断。

​简单记:​

  • 浏览器:​​宏 → 微 → 渲染​​(循环)。
  • Node.js:​​阶段跳,nextTick 总插队​​。

理解差异能避免异步代码的预期错误!

​事件循环机制比喻:Node.js vs 浏览器​

​1. 共同点:快餐店取餐模式​
  • ​共同流程​​:
    都像一家快餐店(主线程),顾客(任务)点餐后:
    1. ​同步任务​​:直接取餐(立即执行)。
    2. ​异步任务​​:拿号排队(放入任务队列),服务员(事件循环)按规则叫号处理。

​2. 核心区别比喻​
​(1)任务队列类型不同​
​浏览器​​Node.js​
​宏任务​​ = 普通顾客(setTimeout、点击事件)
​微任务​​ = VIP顾客(Promise,优先插队)
​宏任务​​ = 分时段顾客(TimersI/OCheck
​微任务​​ = 超级VIP(process.nextTickPromise更优先)
​(2)执行顺序差异​

​浏览器流程​​:

  1. 叫一个普通顾客(执行一个宏任务)。
  2. ​立刻服务所有VIP​​(清空微任务队列)。
  3. 刷新菜单(渲染页面)。
  4. 重复流程。

​Node.js流程​​(6阶段厨房):

  1. ​Timers阶段​​:处理预约的定时器顾客(setTimeout)。
  2. ​Poll阶段​​:盯着取餐口(I/O回调),没人就等新订单。
  3. ​Check阶段​​:立刻处理"现做餐"顾客(setImmediate)。
  4. ​每次切换阶段前​​:
    • 先服务​​老板亲戚​​(process.nextTick)。
    • 再服务VIP(Promise)。

​3. 关键差异场景比喻​
​场景​​浏览器​​Node.js​
​插队优先级​VIP(Promise)和普通VIP(MutationObserver)平等老板亲戚(nextTick)> VIP(Promise
​定时器精度​受厨房忙乱影响(最小延迟4ms)精准预约(系统时钟控制)
​特殊顾客​动画师(requestAnimationFrame现做餐专员(setImmediate
​I/O处理​无固定窗口,随机处理专用取餐口(Poll阶段集中处理)

​4. 代码示例对比​

​浏览器:​

// 比喻:普通顾客和VIP点餐 setTimeout(() => console.log('普通顾客'), 0); // 宏任务 Promise.resolve().then(() => console.log('VIP')); // 微任务 // 输出:VIP → 普通顾客 (VIP优先)

​Node.js:​

// 比喻:分时段+超级VIP插队 setTimeout(() => console.log('预约顾客'), 0); // Timers阶段 setImmediate(() => console.log('现做餐顾客')); // Check阶段 process.nextTick(() => console.log('老板亲戚')); // 最高优先级 // 输出:老板亲戚 → 预约顾客 → 现做餐顾客


​5. 终极口诀​

​浏览器:​
一宏一微一渲染,VIP永远要优先。

​Node.js:​
六阶段轮转不停,老板亲戚赛VIP,Poll阶段等I/O,Immediate断后行。

​一句话记:​

  • 浏览器:​​宏 → 微 → 渲染​​(循环)。
  • Node.js:​​阶段跳,nextTick 永远最先到​​!

通过快餐店比喻,轻松理解两者差异! 

相关文章:

  • ethers.js express vue2 定时任务每天凌晨2点监听合约地址数据同步到Mysql整理
  • 【CMake基础入门教程】第六课:构建静态库 / 动态库 与安装规则(install)
  • MySQL至KES迁移最佳实践
  • 用 Spark 优化亿级用户画像计算:Delta Lake 增量更新策略详解
  • vue3 json 转 实体
  • 2.1、STM32 CAN外设简介
  • Vue3 中 Axios 深度整合指南:从基础到高级实践引言总结
  • MR30分布式IO:产线改造省时 70%
  • 22. 括号生成
  • AI编程工具深度对比:腾讯云代码助手CodeBuddy、Cursor与通义灵码
  • ubuntu20.04如何给appImage创建快捷方式
  • EXILIUM×亚矩云手机:重构Web3虚拟生存法则,开启多端跨链元宇宙自由征途
  • 【JeecgBoot AIGC】打造智能AI应用
  • 51c~嵌入式~PLC~三菱~合集1
  • 记dwz(JUI)前端框架使用之--服务端响应提示框
  • 如何在x86_64 Linux上部署Android Cuttlefish模拟器运行环境
  • Spring Cloud Feign 整合 Sentinel 实现服务降级与熔断保护
  • python + opencv实现简单的文字水印
  • 【CSS 行高陷阱:如何避免文本被截断问题】
  • 【RESTful接口设计规范全解析】URL路径设计 + 动词名词区分 + 状态码 + 返回值结构 + 最佳实践 + 新手常见误区汇总