我想告诉Node.js总是在它退出之前做一些事情,无论出于什么原因- Ctrl+C,一个异常,或任何其他原因。

我试了一下:

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

我启动了这个程序,扼杀了它,然后什么都没发生。我再次启动,按下Ctrl+C,仍然什么都没有发生……


当前回答

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

其他回答

Async-exit-hook似乎是处理这个问题的最新解决方案。它是退出钩子的分叉/重写版本,在退出前支持异步代码。

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

只是想在这里提到死亡包: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
})

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

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

然后你试图通过以下方式杀死它:

child.kill();

这是如何处理[子]事件的:

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

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

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);
  });
};

这段代码拦截未捕获的异常、Ctrl+C和正常退出事件。然后,它在退出前调用一个可选的用户清理回调函数,用一个对象处理所有退出条件。

该模块只是扩展了流程对象,而不是定义另一个事件发射器。如果没有应用程序特定的回调,清理默认为no op函数。这对于我的使用来说已经足够了,当按Ctrl+C退出时,子进程仍在运行。

您可以根据需要轻松添加其他退出事件,例如SIGHUP。注意:根据NodeJS手册,SIGKILL不能有监听器。下面的测试代码演示了使用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