【问题标题】:`exit` event in node.js behaves different than in the manualnode.js 中的 `exit` 事件的行为与手册中的不同
【发布时间】:2017-03-08 23:12:01
【问题描述】:

https://nodejs.org/api/process.html

监听函数只能执行同步操作。这 Node.js 进程将在调用 'exit' 事件后立即退出 导致任何额外工作的侦听器仍在事件循环中排队 被抛弃。例如,在以下示例中,超时 永远不会发生:

process.on('exit', (code) => {
  setTimeout(() => {
    console.log('This will not run');
  }, 0);
});

现在我的 main.js 中有这个:

if (errors) {
    process.exitCode = 1;
}
process.emit("exit");

在具有关闭侦听器等的记录器中,我有一个 mongo 连接和以下内容:

    process.on("exit", (code) => {
        if (this.status.finishedAt === null) {
            this.status.currentState = StatusUpdater.STATE_STOPPED;
            this.status.finishedAt = new Date();
            this.persistStatus()
            .then(() => {
                this.mongoDb.close().then(() => {
                    setTimeout(() => {
                        console.log('byebye');
                        process.exit(code);
                    }, 5000);
                });
            })
            .catch(this.noMongoConnection);
        }
    });

输出为:byebye5 秒后

现在我很困惑。显然我可以在exit 事件触发后进行异步操作。手册说这是不可能的。

什么是对什么是错?

【问题讨论】:

  • exit 事件处理程序中调用process.exit(code); 非常奇怪。我想知道这是否真的会触发你所有的处理程序两次。
  • @Bergi 确实如此,所以我检查 finishedAt 是否未定义。此外,当您触发SIGINT 时,随后也会调用exit 事件。
  • @Bergi 除了我的做法之外,您还有其他关于关闭处理程序的想法吗?我的解决方案的唯一缺点是当有另一个退出侦听器并且当我在另一个侦听器之前执行process.exit() 时有机会不被执行。
  • 诚然,我不知道最佳实践是什么,但我至少会为异步退出处理程序使用不同的事件名称。而且我不会从 mongodb 处理程序调用 process.exit(1),而是从我触发关闭事件的地方调用。

标签: javascript node.js asynchronous listener shutdown-hook


【解决方案1】:

这是因为您手动发出一个名为 exit 的事件,它本身不会导致任何特殊行为。仅当您使用 process.exit

if (errors)
    process.exit(1);

它将具有文档中描述的效果。

【讨论】:

  • 在文档中调用.exit() 和发出exit 事件之间的区别应该更清楚,但您的回答有助于理解它是不一样的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-02
  • 2020-11-19
  • 1970-01-01
  • 2022-12-16
  • 1970-01-01
  • 2012-10-20
  • 2012-11-23
相关资源
最近更新 更多