2016-01-22 59 views

回答

2

操場

讓我們創建連接到管道三個已命名的直通流和觀察個別事件。

var stream = require('stream'); 

function observedStream(name) { 
    var s = new stream.PassThrough({objectMode: true}); 

    s.on('error', function(err) { console.log(name + ': ' + err); }); 
    s.on('data', function(data) { console.log(name + ': ' + data); }); 
    s.on('finish', function() { console.log(name + ': FINISH'); }); 
    s.on('end', function() { console.log(name + ': END'); }); 
    s.on('close', function() { console.log(name + ': CLOSE'); }); 
    s.on('unpipe', function() { console.log(name + ': UNPIPE'); }); 

    return s; 
} 

var s1 = observedStream('S1'), 
    s2 = observedStream('S2'), 
    s3 = observedStream('S3'); 

s1.pipe(s2).pipe(s3); 

標準行爲

寫入管道是直接的。我們只需從每個鏈接中獲得一個data事件。

s1.write('Hello'); 
// S1: Hello 
// S2: Hello 
// S3: Hello 

讓我們來看看當我們結束流時會發生什麼?那裏也沒有驚喜。

s1.end(); 
// S1: FINISH 
// S1: END 
// S2: FINISH 
// S2: UNPIPE 
// S2: END 
// S3: FINISH 
// S3: UNPIPE 
// S3: END 

錯誤處理

讓我們試着發出一個錯誤(當然,如果你叫s1.end()以上,則需要先重新管道)。

s1.emit('error', new Error('bazinga')); 
// S1: Error: bazinga 

注意這裏沒有其他的事情發生。如果沒有任何事情發生,您可以繼續寫入S1。管道未關閉。

事情變得時有一個錯誤「中游」更有趣一點:)

s2.emit('error', new Error('bazinga')); 
// S2: UNPIPE 
// S2: ERROR 

注意自動Node.js加載從S2,但沒有別的unpipes的S1流。即S1流仍然等待有人讀取其數據,並且S2流仍然被傳送到S3中,並且可以(理論上)發送數據。

這是你需要在你的代碼中處理的東西!一種選擇是在S1和S2上調用end()方法。另一種方法是將S1和S2與pipe()方法重新連接。兩者似乎都有效,但這一切都取決於您的特定使用場景。

現金

  1. This article從本·納德爾的博客中指出我朝着正確的方向發展。
  2. This SO question從稍微不同的角度來解決類似的問題。答案中也有一些好的指針。