← [ BACK_TO_NOTES ]

浏览器与 Node.js 事件循环的区别

对比浏览器与 Node.js Event Loop 的共同目标、task/rendering 模型、libuv phases、nextTick 与 V8 microtasks。

#synthesis #evergreen #dev #javascript #nodejs

[!info] related notes

浏览器与 Node.js 事件循环的区别

共同目标

两者都让 JavaScript 在默认单线程、run-to-completion 的执行模型下处理异步 I/O。整个浏览器或 Node.js Runtime 并不是单线程:网络、文件、操作系统、线程池和 Worker 可以在其他执行单元工作;Event Loop 负责让相应 JavaScript callback 在合适时机回来执行。

浏览器:task + microtask checkpoint + rendering

选择一个 task
→ 执行其中的 JavaScript
→ microtask checkpoint
→ 可能 rendering
→ 下一个 task

浏览器必须协调页面更新与用户输入,因此 rendering opportunity 是模型的重要部分。详见 浏览器环境下的 JS Event Loop。

Node.js:libuv phases + nextTick + V8 microtasks

Node.js 没有页面渲染主线,主要面向网络、文件和系统 I/O。用户可见的核心 phases 包括:

pending callbacks
→ idle / prepare
→ poll
→ check
→ close callbacks
→ timers

Node.js 20 / libuv 1.45 起,正常 event-loop iteration 中 timers 在 poll 之后运行;旧资料常画成 timers 位于 poll 前,不应死背为跨版本不变顺序。

  • poll:等待并处理大部分 I/O events;
  • check:执行 setImmediate();
  • close callbacks:执行部分资源关闭回调;
  • timers:执行达到阈值的 timeout / interval callbacks。

process.nextTick() 是额外调度层

process.nextTick() 不属于 libuv phase。实用模型是:

当前 JavaScript callback 返回
→ process.nextTick queue
→ V8 microtasks(Promise / queueMicrotask)
→ 继续 event-loop phase

递归 nextTick 或 microtask 都可能让 I/O / timer 长时间得不到机会。

对比

维度浏览器Node.js
核心场景UI、用户事件、网络网络、文件、系统 I/O
主模型task + microtask checkpoint + renderinglibuv phases + nextTick + V8 microtasks
页面渲染有无
timer后续 task 来源之一timers phase / 机制
I/O 中心浏览器宿主调度poll phase
setImmediate无 Node 同名语义check phase
process.nextTick无Node 特有队列

面试回答

浏览器和 Node.js 的目标相同,都是在 JavaScript 默认单线程执行的前提下实现非阻塞异步,但调度模型不同。浏览器主要看 task、microtask checkpoint 和 rendering;一个 task 执行完后会清空 microtasks,然后浏览器可能渲染。Node.js 没有页面渲染,而是由 libuv 组织 poll、check、timers、close callbacks 等 phases,并且还有优先于普通 V8 microtasks 处理的 process.nextTick queue。出现 setImmediate、I/O callback 或 nextTick 时,不能只套浏览器的“宏任务/微任务”口诀。

学习检查

不看正文回答:

  1. 浏览器与 Node.js Event Loop 的共同目标是什么?
  2. 浏览器为什么必须把 rendering opportunity 纳入调度模型?
  3. Node.js 的 poll、check、timers 分别承担什么职责?
  4. process.nextTick 为什么不能简单归类成浏览器意义上的普通 microtask?
  5. 为什么“宏任务 → 微任务”口诀不足以分析 Node.js 的 setImmediate / I/O callback?
  6. 递归 nextTick 或 microtask 为什么可能造成 starvation?
  7. 给一段同时包含 Promise、setTimeout、I/O、setImmediate 的 Node 代码,先说明需要哪些上下文信息,再预测顺序。
创建于 2025/1/1 更新于 2026/9/30
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本