工具✅
nextTick/setImmediate/setTimeout 区别 ?
答案
核心概念:
- process.nextTick 将回调安排在“当前调用栈清空后、事件循环继续前”执行,优先级高于 Promise microtask 与各阶段回调。
- 常用于:修正同步/异步一致性(避免 Zalgo)、打断递归堆栈、在返回前补充清理或回调。
- 与 setImmediate/setTimeout 不同:nextTick 不进入下一轮事件循环;大量排队会饿死 I/O,应谨慎使用。
- 顺序要点:每个阶段回调结束后→先清空 nextTick 队列→再清空微任务(Promise)→再进入下一阶段。
提示
需要注意在 ESM 模块中由于是异步加载所以 Promise 会在 nextTick 之前执行。此外出现嵌套 Promise 时,会先执行完 Promise 队列再清空 nextTick 队列。
setImmediate 是在下一个事件循环 (event loop) 周期执行,如果在 IO 事件中由于 setImmediate 会处理阶段在 setTiemout 之后所以在 setTimeout 之前执行
延伸阅读
- Node.js process.nextTick — 语义与注意事项
- Node.js 事件循环与计时器 — 阶段与顺序
- Node.js Timers — setImmediate/setTimeout 行为差异
vm 有什么作用?
答案
核心概念:
- vm 提供“在受控上下文中执行 JS”的能力:编译缓存(vm.Script)、隔离上下文(vm.createContext/runInContext)、本进程执行控制(timeout、breakOnSigint)。
- 典型用途:在白名单沙箱里运行用户脚本/表达式、模板渲染求值、热更新代码评估、预编译脚本复用。
- 隔离与注入:newContext 的 global 与宿主不同,默认无 process/require,需显式注入 console/Math 等白名单对象。
- 安全边界:vm 不是强安全沙箱,面对不可信代码应优先用 worker_threads/child_process 做进程/线程级隔离。
- 性能控制:复用 Script 可多次执行提升性能;通过 timeout 限制死循环;必要时配合信号中断。 。
示例说明:
- 基础
- 沙箱逃逸
- 加固示例
延伸阅读:
- Node.js vm — Script、Context、超时与选项
- Node.js vm modules — ESM 加载
- Node.js worker_threads — 可信隔离的替代方案
- Node.js child_process — 进程级隔离与IPC