如何关闭node.js中没有更多数据要发送的流?

如何关闭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

我正在使用node.js并通过打开一个/dev/tty文件从串行端口读取输入,我发送一个命令并读取命令的结果,我想在读取和解析所有数据后关闭流。我知道我已经完成了数据标记的读取。我发现一旦我关闭了流,我的程序就不会终止

下面是我看到的一个示例,但是使用/dev/random缓慢地生成数据(假设您的系统做的不多)。我发现,一旦设备在流关闭后生成数据,进程就会终止

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);