Sha*_*awn 16 javascript event-listener node.js
在下面的代码,我分配一个监听到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')
}
Run Code Online (Sandbox Code Playgroud)
理论上,当回调被触发时,应该自动删除事件监听器(因为我附加了它once),允许进程终止.令人惊讶的是,在这种情况下,进程永远不会终止(你看到的代码就是整个东西,试试吧!).我也尝试手动删除监听器,但这没有任何改变.
还有其他事情发生在这里,我也许没有意识到吗?
Mik*_*e S 29
添加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()
}
Run Code Online (Sandbox Code Playgroud)
此外,作为这样的东西的一般调试工具,有两个(未记录的)函数可以调用以获取保持进程打开的事项列表:
process._getActiveHandles()
process._getActiveRequests()
Run Code Online (Sandbox Code Playgroud)
请参阅节点项目中的此拉取请求以获取背景信息
更新:你问到你后附加事件侦听器unref()倒是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);
}
Run Code Online (Sandbox Code Playgroud)
使用该代码,如果您在setTimeout激发之前按下另一个键(5秒),那么您将看到More data输出到控制台.一旦setTimeout回调触发,该过程将退出.诀窍在于setTimeout创建一个定时器,该过程也保留了引用.由于该过程仍然引用某些内容,因此不会立即退出.一旦计时器触发,它就会释放引用并退出进程.这也表明引用被添加(和删除)到自动需要它们的东西(setTimeout在这种情况下创建的计时器).
只要打电话.end就process.stdin流
对我来说,这是一种更简单(并且有文档记录)的结束流的方式.
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.end();
}
Run Code Online (Sandbox Code Playgroud)
值得注意的是,节点将流设置为回调函数的上下文,因此您只需调用即可 this.end
console.log('Press Enter to allow process to terminate');
process.stdin.once('data', callback);
function callback (data) {
// `this` refers to process.stdin here
console.log('Process can terminate now');
this.end();
}
Run Code Online (Sandbox Code Playgroud)
您还可以发出一个end事件,该事件具有额外的好处,例如在流完成时能够调用函数.
console.log('Press Enter to allow process to terminate');
process.stdin.once('data', function(data) {
console.log('Process can terminate now');
this.emit("end");
});
process.stdin.on('end', function() {
console.log("all done now");
});
Run Code Online (Sandbox Code Playgroud)
这会输出
Press Enter to allow process to terminate
Process can terminate now
all done now
Run Code Online (Sandbox Code Playgroud)
最终的解决方案是使用process.exit.这允许您随时终止程序.
for (var i=0; i<10; i++) {
process.stdout.write( i.toString() );
if (i > 3) process.exit();
}
Run Code Online (Sandbox Code Playgroud)
产量
01234
Run Code Online (Sandbox Code Playgroud)
这将在流回调内部工作,作为子进程的一部分或任何其他代码.
| 归档时间: |
|
| 查看次数: |
9513 次 |
| 最近记录: |