Node.js 如何退出程序?

退出 Node.js 用 process.exit(code):0 表示正常退出,1(或非 0)表示出错退出。注意它会强制终止未完成的异步操作,服务端更推荐让事件循环自然排空退出。本文讲清用法与坑。

最佳实践
Node.js 事件循环与异步任务示意

process.exit(code):0 = 正常退出,非 0(惯例用 1)= 出错退出。

if (someConditionNotMet()) {
  console.error('用法: node <filename> <参数>');
  process.exit(1);   // 参数错误,非 0 退出
}

重要警告:process.exit 是"硬退出"

process.exit() 会尽快强制结束进程,即使还有未完成的异步操作——包括尚未 flush 完的 process.stdout/stderr 写入、进行中的文件写入、未响应的 HTTP 请求,统统丢弃。

// ❌ 可能丢日志:console.log 是异步 flush 的
console.log('important log');
process.exit(0);

更好的方式:让进程自然退出

多数情况不需要显式调用 process.exit——当事件循环中没有待处理任务时,Node 进程自动退出。自然退出会等待仍使事件循环保持活跃的任务;仅有未完成的 Promise、或已 unref 的句柄并不能阻止退出。

想表达退出码又不打断异步操作:

process.exitCode = 1;   // 只设置退出码,不强制退出
// 事件循环排空后进程自动以 1 退出

优雅关闭服务器

服务端收到退出信号时,应该停止接收新连接、等存量请求处理完再退:

process.on('SIGTERM', () => {
  server.close(() => {          // 不再接新连接
    console.log('已处理完存量请求,退出');
    process.exit(0);
  });
});

常见问题(FAQ)

Q:退出码除了 0 和 1 还能用什么?
惯例上 0=成功,1=通用错误,2=用法错误;shell 中 128+N 表示被信号 N 杀死。脚本组合使用时遵守这些惯例能让退出码更有信息量。

Q:程序不退出了,挂着不动?
有未关闭的资源持有事件循环:未关闭的数据库连接、setInterval、监听的 server。用 process._getActiveHandles() 排查,或调 clearInterval/connection.end() 释放。

Q:怎么捕获退出前最后的清理机会?
监听 process.on('exit', ...),但这里面只能做同步操作——异步任务不会被执行。

参考资料

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台