2016-12-15 53 views
0

我很好奇我的PassThrough流,以及为什么它没有关闭后资源我管它关闭。我使用它作为中介,一个资源需要一个ReadableStream,我需要传递给用户一个WriteableStream以允许他们编写底层资源。起初双工流看起来很理想,但需要一些实现,然后我找到了一个PassThrough流。Node.js PassThrough流不能正确关闭?

编辑:https://gist.github.com/four43/46fd38fd0c929b14deb6f1744b63026a

原来的例子: 检查了这一点:最好这个问题的描述这里

const fs = require('fs'); 
const stream = require('stream'); 

const passThrough = new stream.PassThrough({allowHalfOpen: false}); 
const writeStream = new fs.createWriteStream('/tmp/output.txt'); 

passThrough.pipe(writeStream) 
    .on('end',() => console.log('full-end')) 
    .on('close',() => console.log('full-close')) 
    .on('unpipe',() => console.log('full-unpipe')) 
    .on('finish',() => console.log('full-finish')); 
passThrough 
    .on('end',() => console.log('passThrough-end')) 
    .on('close',() => console.log('passThrough-close')) 
    .on('unpipe',() => console.log('passThrough-unpipe')) 
    .on('finish',() => console.log('passThrough-finish')); 

passThrough.end('hello world'); 

实际输出:

passThrough-finish 
passThrough-end 
full-unpipe 
full-finish 
full-close 

好像写边这是否是工作,但PassThrough流的“读取”一侧不会促使关闭e,尽管“allowHalfOpen”选项被传递为false(并且我可以验证选项是否在调试器中)。

我要对所有这一切错了吗?我将如何传播writeStream的结束?

谢谢。

编辑:我发现转换流也是如此,他们只是不结束锥体管道关闭。有没有办法手动关闭它们? transform.end()永远不会导致流抛弃一个“关闭”事件,而是在底层资源成功之前触发“完成”和“结束”事件。

EDIT2:我放在一起这个要点是:https://gist.github.com/four43/46fd38fd0c929b14deb6f1744b63026a

这让我发现,在readable.pipe可读(写)被关闭的情况下正确的写入完成。这会让我相信,当我执行transform.pipe(可写)时,它会关闭变换流的“可读”一面,并且由于我已经用.end()“关闭”了可写的一面,它应该关闭整个流。注意事项:尽管我们从未在测试2中使用它,但阅读仍在抛掷事件。可能是一个隔离问题,但我认为我的超时等待功能确实不错。

回答

0

如果您想在writeStream完成写入则只听为'finish'事件上writeStream

const fs = require('fs'); 
const stream = require('stream'); 

const passThrough = new stream.PassThrough({allowHalfOpen: false}); 
const writeStream = new fs.createWriteStream('/tmp/output.txt'); 

passThrough 
    .on('error', (err) => console.error(err)) 
    .on('end',() => console.log('passThrough-end')) 
    .on('close',() => console.log('passThrough-close')) 
    .on('unpipe',() => console.log('passThrough-unpipe')) 
    .on('finish',() => console.log('passThrough-finish')); 

writeStream 
    .on('error', (err) => console.error(err)) 
    .on('close',() => console.log('full-close')) 
    .on('unpipe',() => console.log('full-unpipe')) 
    .on('finish',() => console.log('full-finish')); 

// passThrough-finish written because all Writes are complete 
passThrough.end('hello world'); 

passThrough.pipe(writeStream); 
+0

我所能知道的,但底层流是不透明的,向我隐瞒。 (我使用我的PassThrough流并将它传递给aws-sdk的s3.upload()方法)。我将编辑我的问题以显示不一致的行为。 – cr125rider

+0

@ cr125rider为什么你关心如果Writable被管道完成?如果您无法访问它,那么它并不重要?在这种情况下,知道您的Readable已关闭应该足够了。另外值得注意的是,[Transform Streams]没有“close”事件(https://nodejs.org/dist/latest-v7.x/docs/api/stream.html#stream_events_finish_and_end) – peteb

+0

为了保证基础流的内容已经完成写入,您需要等待写入流完成。如果你不小心,你会遇到各种奇怪的问题。这实际上是因为一个失败的单元测试正在寻找写完流的东西,读取文件,而不是在那里。 – cr125rider