我想告诉node.js总是在它退出之前做某事,无论出于何种原因 - Ctrl + C,异常或任何其他原因.
我试过这个:
process.on('exit', function (){
console.log('Goodbye!');
});
Run Code Online (Sandbox Code Playgroud)
开始这个过程,杀了它,什么都没发生; 再次启动,按下Ctrl + C,仍然没有发生任何事......
Emi*_*rea 469
您可以为process.on('exit')任何其他情况(SIGINT或未处理的异常)注册处理程序以进行调用process.exit()
process.stdin.resume();//so the program will not close instantly
function exitHandler(options, exitCode) {
if (options.cleanup) console.log('clean');
if (exitCode || exitCode === 0) console.log(exitCode);
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}));
Run Code Online (Sandbox Code Playgroud)
小智 173
下面的脚本允许为所有退出条件设置单个处理程序.它使用特定于应用程序的回调函数来执行自定义清理代码.
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);
});
};
Run Code Online (Sandbox Code Playgroud)
此代码拦截未捕获的异常,Ctrl-C和正常退出事件.然后在退出之前调用单个可选的用户清理回调函数,使用单个对象处理所有退出条件.
该模块只是扩展了过程对象,而不是定义另一个事件发射器.如果没有特定于应用程序的回调,则清除默认为无操作.这对于我在使用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
Run Code Online (Sandbox Code Playgroud)
use*_*519 20
"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.');
});
Run Code Online (Sandbox Code Playgroud)
注意:这似乎会中断sigint,您需要在完成代码后调用process.exit().
lig*_*lbs 19
这可以捕获我可以找到的每个可以处理的退出事件.到目前为止看起来非常可靠和干净.
[`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`].forEach((eventType) => {
process.on(eventType, cleanUpServer.bind(null, eventType));
})
Run Code Online (Sandbox Code Playgroud)
function fnAsyncTest(callback) {
require('fs').writeFile('async.txt', 'bye!', callback);
}
function fnSyncTest() {
for (var i = 0; i < 10; i++) {}
}
function killProcess() {
if (process.exitTimeoutId) {
return;
}
process.exitTimeoutId = setTimeout(() => process.exit, 5000);
console.log('process will exit in 5 seconds');
fnAsyncTest(function() {
console.log('async op. done', arguments);
});
if (!fnSyncTest()) {
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
Run Code Online (Sandbox Code Playgroud)
只是想在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
})
Run Code Online (Sandbox Code Playgroud)
我需要在退出时执行异步清理操作,这个问题的答案都不适合我。
于是我自己尝试了一下,最后发现了这个:
process.once('uncaughtException', async () => {
await cleanup()
process.exit(0)
})
process.once('SIGINT', () => { throw new Error() })
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
141013 次 |
| 最近记录: |