在以下代码中,我使用方法为data
事件分配了一个侦听器。process.stdin
once
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()
有关背景,请参见节点项目中的此拉取请求。
更新:你问到附加的事件监听器,你已经后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
在这种情况下是由计时器创建的)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句