[英]How to properly react to an error event in a Node.js stream pipe-line?
I was struggling with understanding how error handling works inside a Node.js stream pipeline and I ended up experimenting using a simple playground which made things crystal clear for me. 我一直在努力理解错误处理如何在Node.js流管道中工作,最终我使用了一个简单的游乐场进行试验,这对我来说很清楚。
I am posting this as a self-answered question. 我将其发布为一个自我解答的问题。 Perhaps someone finds it helpful :)
也许有人觉得这很有帮助:)
Let's create three named PassThrough streams connected into a pipeline and observe individual events. 让我们创建连接到管道中的三个名为PassThrough的流,并观察各个事件。
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);
Writing to the pipeline is straightforward. 写入管道非常简单。 We simply get a
data
event from each strem. 我们只是从每个strem中获取一个
data
事件。
s1.write('Hello');
// S1: Hello
// S2: Hello
// S3: Hello
Let's see what happens when we end the stream? 让我们看看结束流时会发生什么? No surprises there either.
那里也没有惊喜。
s1.end();
// S1: FINISH
// S1: END
// S2: FINISH
// S2: UNPIPE
// S2: END
// S3: FINISH
// S3: UNPIPE
// S3: END
Let's try emitting an error (obviously, if you called the s1.end()
above, you need to recreate the pipeline first). 让我们尝试发出一个错误(显然,如果您调用了上面的
s1.end()
,则需要先重新创建管道)。
s1.emit('error', new Error('bazinga'));
// S1: Error: bazinga
Notice nothing else happens here. 注意这里什么也没有发生。 You can continue writing to S1 as if nothing happened.
您可以继续写S1,就像什么都没发生一样。 The pipeline is not closed.
管道未关闭。
Things get a little more interesting when there's an error "mid-stream" :) 当出现“中游”错误时,事情会变得更加有趣:)
s2.emit('error', new Error('bazinga'));
// S2: UNPIPE
// S2: ERROR
Notice that Node.js automatically unpipes the S1 stream from S2 but nothing else. 请注意,Node.js会自动从S2取消对S1流的管道传输,除此之外没有其他操作。 Ie the S1 stream still waits for someone to read its data and the S2 stream is still piped into the S3 and can (theoretically) send data.
也就是说,S1流仍在等待某人读取其数据,而S2流仍通过管道传递到S3中,并且可以(理论上)发送数据。
This is something you need to handle in your code! 这是您需要在代码中处理的事情! One option is to call the
end()
methods on S1 and S2. 一种选择是在S1和S2上调用
end()
方法。 Another would be to reconnect S1 and S2 with the pipe()
method. 另一个方法是使用
pipe()
方法重新连接S1和S2。 Both seem to work, but it all depends on your particular usage scenario. 两者似乎都可以工作,但这都取决于您的特定使用情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.