【问题标题】:run async function before process exit在进程退出之前运行异步函数
【发布时间】:2018-01-24 22:57:50
【问题描述】:

我有一个用 Node.js 编写的简单 shell 脚本,我正在尝试在进程退出 (⌃C) 之前进行一些清理。我编写了以下代码,但由于某种原因清理功能没有完成。任何想法为什么?

if (keepAlive) {

   process.stdin.resume();

    ['exit', 'SIGINT'].forEach(function(signal) {

        process.on(signal, function() {

        console.log("Received Signal: '" + signal + "'. Cleaning up...");

        cleanup(function(err) {
          console.log('this function is called but does not finish')
          process.exit();
        });

      });

    });
else {
    process.exit();
}

我正在使用 Node v6.9.2

【问题讨论】:

  • 未完成是什么意思?
  • 您在哪个平台上运行?某些 SIGINT 行为是特定于平台的。
  • @Daniel cleanup 函数被调用,但进程在完成之前退出。
  • @jfriend00 我在 OSX 10.13.2
  • 这与我使用的节点模块有关 Inquirer.js。这就是问题所在:github.com/SBoudrias/Inquirer.js/issues/293。我升级了模块,现在一切正常。

标签: node.js process event-handling


【解决方案1】:

您无法从process.on('exit') 可靠地运行异步代码。这是文档中的引述:

此时无法阻止事件循环的退出,一旦所有“退出”侦听器完成运行,Node.js 进程将终止。

所以,一旦退出侦听器返回(即使它仍在尝试完成它的异步处理),进程就会退出。


对于 SIGINT 处理程序,您应该能够做任何您想做的事情,因为一旦注册了 SIGINT 处理程序,就没有退出进程的默认行为,因此该进程只会在您告诉它时退出。来自文档:

如果这些信号之一 [SIGINT 或 SIGTERM] 安装了侦听器,则其默认行为将被移除(Node.js 将不再退出)。

这意味着如果您正确编写异步处理代码(您的问题中没有显示),您应该能够在异步处理完成后退出。

【讨论】:

  • 据我所知,我应该使用SIGINT,这就是我正在做的事情。我错过了什么吗?
  • @jwerre - 是的,对于非 Windows 平台,它的 SIGINT 应该适用于 Ctrl-C。有关详细信息,请参阅stackoverflow.com/questions/20165605/detecting-ctrlc-in-node-js。也可能是您的异步​​代码在您调用process.exit() 之前没有正确等待异步操作的完成。如果您向我们展示该异步代码,我们可以就此提出建议。
【解决方案2】:

你可以这样做:

process.on("SIGTERM", () => {
    ayncFunction().finally(() => process.exit(0));
});

process.on("SIGINT", () => {
    ayncFunction().finally(() => process.exit(0));
});

process.on("exit", code => {
    console.log(`APP stopped !`);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-12
    • 2023-02-22
    • 2023-03-31
    • 1970-01-01
    • 2017-05-16
    • 1970-01-01
    • 2019-05-21
    • 2016-12-23
    相关资源
    最近更新 更多