2016-01-22 66 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从稍微不同的角度来解决类似的问题。答案中也有一些好的指针。
相关问题