标准答案

  1. 当前 JavaScript 栈清空后,微任务通常在进入下一个事件循环阶段前执行。
  2. process.nextTick 常常优先于普通 Promise 微任务,适合少量 API 兼容性调度,不适合无限递归。
  3. queueMicrotask 与 Promise.then 都适合安排微任务,但错误传播和返回值形式不同。
  4. 长链微任务会让事件循环迟迟进入 poll 或 timers,表现为 I/O 和 P99 延迟升高。

题目解析

当前 JavaScript 栈清空后,Promise reaction 和 queueMicrotask 会在进入后续事件循环阶段前执行;process.nextTick 是 Node 独有的更高优先级调度。它们都仍然在主线程运行。

nextTick 适合少量兼容性调度,不是让出主线程的工具。递归 nextTick 或微任务会让 timers、poll 和网络回调迟迟得不到机会。

错误传播和返回值也有差异:Promise 链可以 reject,queueMicrotask 的异常直接进入运行时处理。测试既要验证顺序,也要验证在真实 I/O 下的延迟和吞吐。

常见误区

  • 误区:把 nextTick 当作让出主线程。改正:它会优先运行,长链反而可能阻塞 I/O,应使用 setImmediate 或拆分任务。
  • 误区:在循环中无限 queueMicrotask。改正:设置工作批次和让出点,避免微任务饥饿事件循环。
  • 误区:只测 Promise 回调顺序。改正:同时测事件循环延迟、定时器误差和 I/O 完成时间。

作者信息