1
我很努力地理解錯誤處理是如何在Node.js流管道內工作的,並且我最終嘗試使用一個簡單的操場來讓事情變得清晰。如何正確響應Node.js流管道中的錯誤事件?
我發佈這是一個自我回答的問題。也許有人認爲它有用:)
我很努力地理解錯誤處理是如何在Node.js流管道內工作的,並且我最終嘗試使用一個簡單的操場來讓事情變得清晰。如何正確響應Node.js流管道中的錯誤事件?
我發佈這是一個自我回答的問題。也許有人認爲它有用:)
讓我們創建連接到管道三個已命名的直通流和觀察個別事件。
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()
方法重新連接。兩者似乎都有效,但這一切都取決於您的特定使用場景。