如何关闭node.js中没有更多数据要发送的流?
我正在使用node.js并通过打开一个/dev/tty文件从串行端口读取输入,我发送一个命令并读取命令的结果,我想在读取和解析所有数据后关闭流。我知道我已经完成了数据标记的读取。我发现一旦我关闭了流,我的程序就不会终止 下面是我看到的一个示例,但是使用/dev/random缓慢地生成数据(假设您的系统做的不多)。我发现,一旦设备在流关闭后生成数据,进程就会终止如何关闭node.js中没有更多数据要发送的流?,node.js,stream,node.js-stream,Node.js,Stream,Node.js Stream,我正在使用node.js并通过打开一个/dev/tty文件从串行端口读取输入,我发送一个命令并读取命令的结果,我想在读取和解析所有数据后关闭流。我知道我已经完成了数据标记的读取。我发现一旦我关闭了流,我的程序就不会终止 下面是我看到的一个示例,但是使用/dev/random缓慢地生成数据(假设您的系统做的不多)。我发现,一旦设备在流关闭后生成数据,进程就会终止 var util = require('util'), PassThrough = require('stream').Pass
var util = require('util'),
PassThrough = require('stream').PassThrough,
fs = require('fs');
// If the system is not doing enough to fill the entropy pool
// /dev/random will not return much data. Feed the entropy pool with :
// ssh <host> 'cat /dev/urandom' > /dev/urandom
var readStream = fs.createReadStream('/dev/random');
var pt = new PassThrough();
pt.on('data', function (data) {
console.log(data)
console.log('closing');
readStream.close(); //expect the process to terminate immediately
});
readStream.pipe(pt);
此时,节点将挂起而不退出。这是在10.28。您正在关闭
/dev/random
流,但是您仍然有一个侦听器用于传递上的'data'
事件,它将保持应用程序运行,直到传递被关闭
我猜读取流中有一些缓冲数据,在刷新之前,传递不会关闭。但这只是一个猜测
要获得所需的行为,您可以在传递过程中删除事件侦听器,如下所示:
pt.on('data', function (data) {
console.log(data)
console.log('closing');
pt.removeAllListeners('data');
readStream.close();
});
而不是使用
readStream.close(),
试用
readStream.pause().
但是,如果您使用的是最新版本的node,请使用isaacs从模块创建的对象包装readstream,如下所示:
var Readable = require('stream').Readable;
var myReader = new Readable().wrap(readStream);
然后用myReader代替readStream
祝你好运!告诉我这是否有效。不,打印结束后流程仍停留在那里。您在哪个版本的节点和哪个平台上运行此操作?我在Windows7上用0.10.16尝试了你的代码,得到了你代码的描述行为,并在
pt
上删除了侦听器,修复了它。我没有/dev/random
,我是从一个足够大的文件中读取的,这些读取是在64k块中进行的。进程在读取了包含我的更改的第一个块后返回,它等待包含原始代码的第二个块。我正在linux平台上运行10.21。我希望您的测试能够正常工作,因为您的流将持续包含数据/dev/random不会。您可以打开/dev/random,将其附加到一个on('data')上,它将一直坐在那里,直到有一些数据要发送。你的大文件发送第一个数据块,你得到数据事件,然后删除你的侦听器并关闭流,但流仍然有数据。我刚刚尝试使用节点0.10.18,在OSX上读取/dev/random
,我观察到了相同的行为:如果我将侦听器保持在pt上,那么我会收到2条“关闭”消息,但是如果我在第一个“数据”事件中删除侦听器,那么我就不会得到第二个。我不知道为什么它不能在Linux上运行。看起来您的系统已经足够让/dev/random传递数据了。您是否可以尝试删除close和removeAllListeners,看看在接收数据事件之间是否有长时间的暂停,或者是否接收到稳定的事件流?也许这会有所帮助?我猜这没用吧?如果你没注意到的话,这个问题的OP将他们的答案放在问题的底部(至少对我来说,一开始并不是很明显,问题的底部不仅仅是更多的问题)。这是一种奇怪的行为。OP的代码立即在Mac Os(节点v0.10.21)中退出。可能我没有找到它,但通过关闭与数据库的连接(mongoose)解决了这个问题。除了代码中创建的流之外,我没有其他连接。这样做时,我得到了一个很好的堆栈跟踪。:)_stream_readable.js:730抛出新错误('现在无法切换到旧模式');这是有关的,已在中修复。我已根据您的错误更改了答案。实际上,我的答案只与旧的节点版本相关。对不起。
var Readable = require('stream').Readable;
var myReader = new Readable().wrap(readStream);