在node.js退出前执行清理操作

我想告诉node.js总是在退出之前做一些事情,无论出于何种原因–Ctrl + C,exception或其他原因。

我试过这个:

process.on('exit', function (){ console.log('Goodbye!'); }); 

开始这个过程,把它杀死,什么也没有发生。 再次启动,按Ctrl + C,仍然没有发生…

更新:

您可以注册process.on('exit')的处理程序,并在其他任何情况下( SIGINT或未处理的exception)来调用process.exit()

 process.stdin.resume();//so the program will not close instantly function exitHandler(options, err) { if (options.cleanup) console.log('clean'); if (err) console.log(err.stack); if (options.exit) process.exit(); } //do something when app is closing process.on('exit', exitHandler.bind(null,{cleanup:true})); //catches ctrl+c event process.on('SIGINT', exitHandler.bind(null, {exit:true})); // catches "kill pid" (for example: nodemon restart) process.on('SIGUSR1', exitHandler.bind(null, {exit:true})); process.on('SIGUSR2', exitHandler.bind(null, {exit:true})); //catches uncaught exceptions process.on('uncaughtException', exitHandler.bind(null, {exit:true})); 

下面的脚本允许有一个处理程序的所有退出条件。 它使用特定于应用程序的callback函数来执行自定义清理代码。

cleanup.js

 // Object to capture process exits and call app specific cleanup function function noOp() {}; exports.Cleanup = function Cleanup(callback) { // attach user callback to the process event emitter // if no callback, it will still exit gracefully on Ctrl-C callback = callback || noOp; process.on('cleanup',callback); // do app specific cleaning before exiting process.on('exit', function () { process.emit('cleanup'); }); // catch ctrl+c event and exit normally process.on('SIGINT', function () { console.log('Ctrl-C...'); process.exit(2); }); //catch uncaught exceptions, trace, then exit normally process.on('uncaughtException', function(e) { console.log('Uncaught Exception...'); console.log(e.stack); process.exit(99); }); }; 

该代码拦截未捕获的exception,Ctrl-C和正常的退出事件。 然后在退出之前调用一个可选的用户清理callback函数,用一个对象处理所有退出条件。

模块简单地扩展了过程对象,而不是定义另一个事件发射器。 没有应用程序特定的callback,清理默认为no op函数。 这足以让我在使用Ctrl-C退出subprocess时保持运行状态。

您可以根据需要轻松添加其他退出事件,例如SIGHUP。 注意:根据NodeJS手册,SIGKILL不能有监听器。 下面的testing代码演示了使用cleanup.js的各种方法

 // test cleanup.js on version 0.10.21 // loads module and registers app specific cleanup callback... var cleanup = require('./cleanup').Cleanup(myCleanup); //var cleanup = require('./cleanup').Cleanup(); // will call noOp // defines app specific callback... function myCleanup() { console.log('App specific cleanup code...'); }; // All of the following code is only needed for test demo // Prevents the program from closing instantly process.stdin.resume(); // Emits an uncaught exception when called because module does not exist function error() { console.log('error'); var x = require(''); }; // Try each of the following one at a time: // Uncomment the next line to test exiting on an uncaught exception //setTimeout(error,2000); // Uncomment the next line to test exiting normally //setTimeout(function(){process.exit(3)}, 2000); // Type Ctrl-C to test forced exit 

“exit”是节点在内部完成事件循环时触发的事件,当您从外部终止进程时,它不会被触发。

你正在寻找的是在SIGINT上执行的东西。

http://nodejs.org/api/process.html#process_signal_events上的文档给出了一个例子:;

侦听信号情报的例子:

 // 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()。

只是想在这里提到death包: https : //github.com/jprichardson/node-death

例:

 var ON_DEATH = require('death')({uncaughtException: true}); //this is intentionally ugly ON_DEATH(function(signal, err) { //clean up code here }) 

io.js有一个exit和一个beforeExit事件,它们是你想要的。

 var fs = require('fs'); function async(callback) { fs.writeFile('async.txt', 'bye!', callback); } function sync() { for (var i = 0; i < 10; i++) {} return true; } function killProcess() { if (process.exitTimeoutId){ return; } process.exitTimeoutId = setTimeout(process.exit, 5000); console.log('process will exit in 5 seconds'); async(function() { console.log('async op. done', arguments); }); if (sync()) { console.log('sync op. done'); } } // https://nodejs.org/api/process.html#process_signal_events process.on('SIGTERM', killProcess); process.on('SIGINT', killProcess); process.on('uncaughtException', function(e) { console.log('[uncaughtException] app will be terminated: ', e.stack); killProcess(); /** * @https://nodejs.org/api/process.html#process_event_uncaughtexception * * 'uncaughtException' should be used to perform synchronous cleanup before shutting down the process. * It is not safe to resume normal operation after 'uncaughtException'. * If you do use it, restart your application after every unhandled exception! * * You have been warned. */ }); console.log('App is running...'); console.log('Try to press CTRL+C or SIGNAL the process with PID: ', process.pid); process.stdin.resume(); // just for testing 

在另一个节点进程产生进程的情况下,如:

 var child = spawn('gulp', ['watch'], { stdio: 'inherit', }); 

而你以后试图杀死它,通过:

 child.kill(); 

这就是你如何处理[对小孩]的事件:

 process.on('SIGTERM', function() { console.log('Goodbye!'); });