Node.js的事件循环和浏览器有什么区别?

一、核心区别一句话总结

👉 浏览器:宏任务 + 微任务(简单模型)

👉 Node.js:6 个阶段(phases)+ 两种微任务队列(更复杂)


二、浏览器事件循环(简单模型)

执行流程

  1. 执行一个宏任务(script / setTimeout / I/O)

  2. 执行所有微任务(Promise.then / MutationObserver)

  3. 渲染(如果需要)

  4. 进入下一个循环


示例

复制代码
console.log('1');

setTimeout(() => console.log('2'), 0);

Promise.resolve().then(() => console.log('3'));

console.log('4');

👉 输出:

复制代码
1
4
3
2

关键点

  • 微任务优先级高于宏任务

  • 每个宏任务执行完,都会清空微任务队列


三、Node.js 事件循环(重点)

Node.js 不是简单的"宏任务/微任务",而是 6 个阶段(phases)循环执行


Node.js 六大阶段

顺序如下:

复制代码
1. timers(setTimeout / setInterval)
2. pending callbacks
3. idle, prepare(内部使用)
4. poll(I/O 核心阶段)
5. check(setImmediate)
6. close callbacks

👉 每个阶段都有自己的队列


可视化理解(流程)

复制代码
timers → pending → poll → check → close
          ↑             ↓
        (循环继续)

四、Node.js 的"微任务"更特殊

Node.js 有 两个微任务队列

1️⃣ process.nextTick(最高优先级)

2️⃣ Promise.then(普通微任务)


执行优先级

复制代码
当前阶段执行完
  ↓
先执行 nextTick 队列
  ↓
再执行 Promise 微任务
  ↓
进入下一个阶段

示例(Node 面试高频)

复制代码
setTimeout(() => console.log('timeout'));

setImmediate(() => console.log('immediate'));

process.nextTick(() => console.log('nextTick'));

Promise.resolve().then(() => console.log('promise'));

👉 输出(Node):

复制代码
nextTick
promise
timeout / immediate(不确定)

五、Node vs 浏览器 对比(重点总结)

对比点 浏览器 Node.js
结构 宏任务 + 微任务 6 个阶段
微任务类型 Promise nextTick + Promise
微任务执行时机 宏任务后 每个阶段后
优先级最高 Promise process.nextTick
setImmediate ❌ 没有 ✅ 有
I/O处理 简单 poll阶段(核心)

六、最容易踩坑的区别(很重要)

1️⃣ nextTick 会"饿死"事件循环

复制代码
function loop() {
  process.nextTick(loop);
}
loop();

👉 会导致:

  • I/O 永远不执行

  • 事件循环卡死

⚠️ 浏览器没有这个问题


2️⃣ setTimeout vs setImmediate(Node)

复制代码
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));

👉 在不同环境下顺序可能不同:

  • 主线程:不确定

  • I/O回调中:setImmediate 更快


七、一句话面试总结(可以直接背)

👉 浏览器事件循环是"宏任务 + 微任务"的简单模型,而 Node.js 是基于 libuv 的多阶段事件循环(timers、poll、check 等),并且 Node 中存在两个微任务队列(process.nextTick 和 Promise),其中 nextTick 优先级最高。

相关推荐
__zRainy__14 小时前
Node.js Web 框架选型指南:从 Express 到 Hono 的全景对比
前端·node.js·express·koa·nestjs·egg·fastify
__zRainy__19 小时前
Node系列 · Node基础:net 模块
后端·node.js
嘟嘟07171 天前
从浏览器到 hello world:Docker + nginx 反向代理 + Node 最小服务器一次讲清
docker·容器·node.js
FungLeo1 天前
Node 后端实战 · 老系统数据迁移怎么不出乱子?V1→V2 重构实战与 3 个生产坑
node.js·serverless·数据库迁移·d1 数据库
今日无bug1 天前
Tool Use 工具调用 —— 让LLM缸中大脑突破物理限制的3个阶段
node.js·llm·agent
蹦跶的小羊羔1 天前
Sublime 调用的 py 命令找不到
编辑器·sublime text
FZdydz1 天前
大禹电子多普勒流量计小管径生活污水排污口流量监测应用案例
百度·编辑器·新浪微博
To_OC2 天前
装完 ESLint 它一声不吭?我还以为代码写得多好
后端·node.js·eslint
FungLeo2 天前
Node 后端实战 · 列表查询到底怎么写?一个通用 DSL 封装,过滤分页排序一次搞定
数据库·node.js·serverless·dsl 封装·通用列表查询
_codemonster2 天前
npm run dev 是在开发模式运行,怎么在生产环境运行
前端·npm·node.js