在下面的代码中,我使用 once
方法为 process.stdin
的 data
事件分配了一个监听器。
console.log('Press Enter to allow process to terminate')
process.stdin.once('data', callback)
function callback (data) {
console.log('Process can terminate now')
}
理论上,当回调触发时,事件监听器应该被自动移除(因为我用 once
附加了它),允许进程终止。令人惊讶的是,在这种情况下,进程永远不会终止(你看到的代码就是全部,试试吧!)。我也尝试过手动删除监听器,但这并没有改变。
这里还有什么我可能没有意识到的事情吗?
最佳答案
将 data
事件监听器添加到 process.stdin
添加对它的引用以保持进程打开。即使在删除所有事件监听器之后,该引用仍然存在。您可以在回调中手动 unref()
它,如下所示:
console.log('Press Enter to allow process to terminate')
process.stdin.once('data', callback)
function callback (data) {
console.log('Process can terminate now')
process.stdin.unref()
}
此外,作为此类东西的通用调试工具,您可以调用两个(未记录的)函数来获取保持进程打开的事物列表:
process._getActiveHandles()
process._getActiveRequests()
见 this pull request在后台的 Node 项目中。
更新:您在 unref()
'd process.stdin
后询问了附加事件监听器的问题。这是一个简单的示例,显示监听器确实附加了自身和函数:
console.log('Press Enter to allow process to terminate')
process.stdin.once('data', callback)
function callback (data) {
console.log('Unreferencing stdin. Exiting in 5 seconds.')
process.stdin.unref()
process.stdin.once('data', function(data) {
console.log('More data')
})
setTimeout(function() {
console.log('Timeout, Exiting.')
}, 5000);
}
使用该代码,如果您在 setTimeout
触发(5 秒)之前按另一个键,那么您将看到 More data
输出到控制台。一旦 setTimeout
的回调触发,进程将退出。诀窍是 setTimeout
正在创建一个计时器,该进程也保留一个引用。由于该进程仍然引用了某些内容,因此它不会立即退出。一旦计时器触发,它就会释放引用并退出进程。这也表明引用被添加(和删除)到自动需要它们的事物(在这种情况下由 setTimeout
创建的计时器)。
关于javascript - 为什么删除所有监听器后我的 Node.js 进程不会终止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26004519/