2016-12-15 6 views
0

PassThroughストリームが不思議で、なぜリソースが閉じた後に閉じないのですか?私はそれをメディエータとして使用していますが、1つのリソースにはReadableStreamが必要です。ユーザーにWriteableStreamを渡して、基になるリソースを書き込めるようにする必要があります。最初はDuplexストリームが理想的だと思われましたが実装が必要でしたが、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()は、ストリームに "close"イベントを送り込ませません。基底リソースが成功する前に起動される "finish"イベントと "end"イベントだけです。

EDIT2:私は一緒にこの要点を置く:https://gist.github.com/four43/46fd38fd0c929b14deb6f1744b63026a

時に書き込み可能な仕上げreadable.pipe(書き込み可能)で読めるが適切に閉鎖されたことを私に示すこと。そうすれば、私はtransform.pipe(書き込み可能)を行うと、変換ストリームの "読み込み可能な"側を閉じ、書き込み可能な側を.end()で "閉じて"いるので、全体を閉じなければならないと信じていますストリーム。私たちがテスト2で使っていないにもかかわらず、読んでしまうイベントは、孤立問題かもしれませんが、私のタイムアウト待ちはかなりうまくいくと思います。

答えて

0

あなたはwriteStreamはちょうど私ができるが、基になるストリームが不透明であり、私から隠されていることを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

'finish'イベントをリッスン、その後の書き込みに行われたときに知りたい場合。 (私はPassThroughストリームを使ってaws-sdkのs3.upload()メソッドにパイプしています)。一貫性のない行動を示すために質問を編集します。 – cr125rider

+0

@ cr125riderなぜWritableが終了するようにパイプされていても気になりますか?あなたがそれにアクセスできない場合、それは問題ではありませんか?その場合、あなたのReadableが閉じていることを知っていれば十分です。また、[Transform Streams](https://nodejs.org/dist/latest-v7.x/docs/api/stream.html#stream_events_finish_and_end)の「close」イベントがないことにも注目してください。 – peteb

+0

保証するために基本ストリームの内容が書き込みを完了した場合、書き込みストリームが完了するまで待つ必要があります。あなたが慎重でない場合、あなたはあらゆる種類の奇妙な問題にぶつかるでしょう。これは実際には、失敗した単体テストが、ストリームへの書き込みを完了した何かを探していて、ファイルを読み込んでいないために出てきました。 – cr125rider

関連する問題