我想告诉Node.js总是在它退出之前做一些事情,无论出于什么原因- Ctrl+C,一个异常,或任何其他原因。
我试了一下:
process.on('exit', function (){
console.log('Goodbye!');
});
我启动了这个程序,扼杀了它,然后什么都没发生。我再次启动,按下Ctrl+C,仍然什么都没有发生……
我想告诉Node.js总是在它退出之前做一些事情,无论出于什么原因- Ctrl+C,一个异常,或任何其他原因。
我试了一下:
process.on('exit', function (){
console.log('Goodbye!');
});
我启动了这个程序,扼杀了它,然后什么都没发生。我再次启动,按下Ctrl+C,仍然什么都没有发生……
当前回答
"exit"是一个在节点内部完成它的事件循环时触发的事件,当你在外部终止进程时不会触发。
你要做的是在SIGINT上执行一些东西。
http://nodejs.org/api/process.html#process_signal_events上的文档给出了一个例子:
监听SIGINT的例子:
// Start reading from stdin so we don't exit.
process.stdin.resume();
process.on('SIGINT', function () {
console.log('Got SIGINT. Press Control-D to exit.');
});
注意:这似乎会中断sigint,当你完成代码时,你需要调用process.exit()。
其他回答
io.js有一个exit和一个beforeExit事件,它们做你想做的事情。
Async-exit-hook似乎是处理这个问题的最新解决方案。它是退出钩子的分叉/重写版本,在退出前支持异步代码。
这将捕获我能找到的可以处理的每个退出事件。目前看来很可靠,也很干净。
[`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`].forEach((eventType) => {
process.on(eventType, cleanUpServer.bind(null, eventType));
})
在进程由另一个节点进程生成的情况下,例如:
var child = spawn('gulp', ['watch'], {
stdio: 'inherit',
});
然后你试图通过以下方式杀死它:
child.kill();
这是如何处理[子]事件的:
process.on('SIGTERM', function() {
console.log('Goodbye!');
});
在尝试了其他答案之后,下面是我对这个任务的解决方案。实现这种方式可以帮助我将清理工作集中在一个地方,防止重复处理清理工作。
我想将所有其他退出代码路由到“退出”代码。
const others = [`SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`]
others.forEach((eventType) => {
process.on(eventType, exitRouter.bind(null, { exit: true }));
})
exitRouter所做的是调用process.exit()
function exitRouter(options, exitCode) {
if (exitCode || exitCode === 0) console.log(`ExitCode ${exitCode}`);
if (options.exit) process.exit();
}
在'exit'上,使用一个新函数处理清理
function exitHandler(exitCode) {
console.log(`ExitCode ${exitCode}`);
console.log('Exiting finally...')
}
process.on('exit', exitHandler)
为了演示目的,这是我要点的链接。在文件中,我添加了一个setTimeout来伪造进程运行。
如果你运行node node-exit-demo.js,什么都不做,那么2秒后,你会看到日志:
The service is finish after a while.
ExitCode 0
Exiting finally...
否则,如果在服务结束之前,你按ctrl+C终止,你会看到:
^CExitCode SIGINT
ExitCode 0
Exiting finally...
发生的情况是Node进程最初以代码SIGINT退出,然后路由到process.exit(),最后以退出代码0退出。