2016-12-15 52 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