CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Node.js 运行时进阶/课时/定时器与 nextTick
RawBlame
课时目录12 节

Node.js 运行时进阶

  1. 01运行时进阶概览
  2. 02定时器与 nextTick
  3. 03回调与错误栈
  4. 04子进程
  5. 05Worker Threads
  6. 06Cluster 与多进程
  7. 07垃圾回收
  8. 08调试 Node
  9. 09APM 与生产监控
  10. 10CLI 工具链
  11. 11global 与内置模块
  12. 12综合练习

定时器与 nextTick

setTimeout、setImmediate、process.nextTick。

30 分钟

定时器与 nextTick

nodejs-essentials 的 node-async 介绍了 Event Loop 概念。本课深入 定时器 API 与调度优先级:setTimeout、setInterval、setImmediate、process.nextTick——理解它们何时执行、为何顺序有时「反直觉」。

学习目标

  • 区分宏任务(timers、I/O、check)与微任务(nextTick、Promise)
  • 正确使用 setImmediate 与 setTimeout(fn, 0) 的场景差异
  • 避免 nextTick 递归导致 Event Loop 饥饿

四类调度 API

API阶段典型用途
process.nextTick(fn)当前阶段结束后、下一轮 Loop 前保证回调在 I/O 之前执行
Promise.then / queueMicrotask微任务队列异步链、与 nextTick 交错
setTimeout / setIntervaltimers 阶段延迟、周期任务
setImmediatecheck 阶段I/O 回调之后尽快执行

Node 文档:nextTick 优先级高于 Promise 微任务(与浏览器略有不同)。

执行顺序实验

console.log("1 sync");

setTimeout(() => console.log("2 setTimeout"), 0);
setImmediate(() => console.log("3 setImmediate"));

process.nextTick(() => console.log("4 nextTick"));

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

console.log("6 sync");

主脚本里常见输出:1 → 6 → 4 → 5 → 2/3(2 与 3 在 I/O 上下文外顺序不保证)。在 fs.readFile 回调内 再设 timeout 与 immediate,则 immediate 通常先于 timeout——因为 check 阶段紧跟 poll。

setTimeout 的坑

  • 最小延迟:浏览器与 Node 对 0ms 都有下限(通常 1ms 量级),不能当作「立即」。
  • drift:setInterval 不补偿执行耗时,长任务会导致间隔「挤在一起」;精确周期用 setTimeout 链或 timers/promises 的 scheduler.wait(Node 实验 API)。
  • unref:timer.unref() 让定时器不阻止进程退出——CLI 一次性脚本常用。
const t = setTimeout(() => {}, 60_000);
t.unref(); // 无其他 handle 时进程可正常结束

nextTick 适用与滥用

适用:在事件回调里抛错前做同步清理;保证 emit('error') 前 listener 已注册(见 nva-events)。

滥用:递归 process.nextTick 会 饿死 I/O 与 timers——相当于占满微任务队列。

// 反模式:阻塞 Event Loop
function spin() {
  process.nextTick(spin);
}

CPU 密集应改用 nrt-worker 或拆分到 nrt-child。

与 Spring @Scheduled 对照

Node timersSpring
线程单线程回调线程池调度
精度毫秒级,受 Loop 负载影响cron / fixedRate 更语义化
取消clearTimeout / clearInterval@Scheduled 需容器管理

练习

  • 运行上文顺序实验,在 readFile 回调内再测 setImmediate vs setTimeout
  • 写 debounce(fn, ms),内部用 setTimeout + clearTimeout
  • 对一次性 CLI 脚本尝试 timer.unref(),观察进程是否提前退出

小结

nextTick 最快但最危险;setImmediate 贴近 I/O 后;setTimeout 看 timers 阶段。 下一课回调与错误栈——异步里 stack trace 为何「断档」。

加载本节练习…
← 上一课运行时进阶概览下一课 →回调与错误栈