所有侦听器都删除后,为什么我的Node.js进程不终止? [英] Why doesn't my Node.js process terminate once all listeners have been removed?

查看:114
本文介绍了所有侦听器都删除后,为什么我的Node.js进程不终止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,我使用once方法将侦听器分配给process.stdindata事件.

In the following code, I assign a listener to the data event of process.stdin with the once method.

console.log('Press Enter to allow process to terminate')
process.stdin.once('data', callback)

function callback (data) {
    console.log('Process can terminate now')
}

理论上,触发回调后,应自动删除事件侦听器(因为我将它附加到了once),从而允许进程终止.令人惊讶的是,在这种情况下,该过程永远不会终止(您所看到的代码是完整的,请尝试!).我还尝试过手动删除侦听器,但这没有任何改变.

In theory, when the callback has fired, the event listener should be automatically removed (because I attached it with once), allowing the process to terminate. Surprisingly, in this case, the process never terminates (The code you see is the whole thing, try it!). I also tried manually removing the listener, but that changes nothing.

这里还有其他我可能没有意识到的事情吗?

Is there something else going on here that I don't realise perhaps?

推荐答案

data事件侦听器添加到process.stdin会添加对它的引用,以使进程保持打开状态.即使删除了所有事件侦听器,该引用也会保留在原位.您可以做的是在回调中手动unref(),如下所示:

Adding the data event listener to process.stdin add a reference to it that keeps the process open. That reference stays in place even after removing all event listeners. What you can do is manually unref() it in your callback, like so:

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

此外,作为用于此类操作的常规调试工具,您可以调用两个(未记录的)函数来获取使进程保持打开状态的列表:

Also, as a general debugging tool for stuff like this, there are two (undocumented) functions that you can call to get a list of things keeping your process open:

process._getActiveHandles()
process._getActiveRequests()

请参阅节点项目中的此提取请求背景.

更新:您问过unref() process.stdin后是否附加事件监听器.这是一个简单的示例,显示了侦听器确实附加了自身并起作用:

Update: You asked about attaching event listeners after you've unref()'d process.stdin. Here's a quick example showing that the listener does attach itself and function:

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创建的计时器).

With that code, if you press another key before the setTimeout fires (5 seconds), then you'll see More data output to the console. Once the setTimeout's callback fires, the process will exit. The trick is that setTimeout is creating a timer which the process also keeps a reference too. Since the process still has a reference to something, it won't exit right away. Once the timer fires, the reference it released and the process exits. This also shows that references are added (and removed) to things that need them automatically (the timer created by setTimeout in this case).

这篇关于所有侦听器都删除后,为什么我的Node.js进程不终止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆