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()
方法重新连接。两者似乎都有效,但这一切都取决于您的特定使用场景。