2015-10-17 55 views
3

確定是否需要等待process.stdout上的drain事件的標準建議是在寫入時檢查它是否返回false。將節點管道連接到標準輸出 - 如何判斷是否排幹?

我應該如何檢查是否已經通過管道傳輸另一個流?在所有輸出實際寫入之前,似乎該流可以發出finish。我可以做些什麼嗎?

upstreamOfStdout.on('finish', function(){ 
    if(!process.stdout.write('')) { 
    process.stdout.on('drain', function() { done("I'm done"); }); 
    } 
    else { 
    done("I'm done"); 
    } 
}); 
upstreamOfStdout.pipe(process.stdout); 

我更喜歡不依賴於任何流的內部的答案。只要流符合節點流接口,那麼執行此操作的規範方法是什麼?

EDIT

較大的範圍內是一個包裝:

new Promise(function(resolve, reject){ 
    stream.on(<some-event>, resolve); 
    ... (perhaps something else here?) 
}); 

其中stream可以process.stdout或別的東西,其具有另一個通過流管道輸送到它。

無論何時調用resolve,我的程序都會退出 - 我認爲Promise代碼可以讓程序保持活動狀態,直到所有的promise都被解決。

我已經多次遇到這種情況,並一直使用黑客來解決問題(例如process.stdout中有幾個私有成員是有用的。)但是我真的想要一勞永逸地解決這個問題(或者學習它是一個錯誤,所以我可以跟蹤這個問題,並在解決問題時解決它,至少):我怎麼知道另一個下游流是否完成處理其輸入?

回答

2

首先,據我所知,從documentation,該流不會發出事件,所以不太可能依靠這個。

而且,從上面提到的文件中,drain事件似乎是用於通知關於當stream已準備好接受更多數據一旦.write方法返回false用戶。無論如何,你可以推斷出這意味着所有其他數據都被寫入了。從write方法的文檔確實我們推斷出false的值(也就是停止推送數據)並不是強制性的,您可以自由地忽略它,但後續數據可能會填充到內存中,使其用於增長。因此,基於我對單獨文檔的假設,我想你可以依靠drain事件來知道何時所有數據都被很好地處理或可能被刷新。

也就是說,它看起來還沒有一個明確的方式來確定何時所有數據已被有效地發送到控制檯。

最後,您可以監聽管道streamend事件,以瞭解它何時已完全使用,無論它是否已寫入控制檯或數據仍在控制檯流中緩衝。 當然,你也可以自由地忽略這個問題,因爲一個完全消耗的流應該被node.js很好地處理,因此被丟棄,並且一旦你將它傳送到第二流,你就不必處理它了。

+0

我遇到的問題是,如果聽不到排水,程序會在所有內容寫完之前終止,但如果我傾聽排水,它有時候不會發生。我認爲只有當數據被緩衝時纔會發出漏極,但我不知道數據是否被緩衝。他們似乎沒有書面的方式來問一個流是否完成了寫作。 – shaunc

+0

當'write'方法返回'false'時,緩衝發生,或者至少這就是文檔所說的。因此,「排水」事件是在這種情況之後。請記住,只要您在要執行的循環中有一些有意義的內容,程序就會保持活躍狀態​​。你有沒有嘗試過聽第一個「end」事件,而不是最後一個? – skypjack

+0

我相信'end'已被棄用於可寫流 - 'finish'是要聽的事件。從我的示例代碼中可以看到,我確實聽完了。關於「寫入方法返回false時發生緩衝」的說法是正確的 - 當前的問題是當由於使用管道發送數據而無法看到「寫入」返回時要執行的操作。例如,在收到上游官方批准的「finish」後寫入一個空字符串?我非常感謝維護者的迴應,或者對他們寫的東西的引用,因爲doc看起來沒有結果。 – shaunc

相關問題