http://www.jdon.com/idea/nodejs/io-stream3.html
这个概念和pull-stream库貌似没啥关系,还是记录下吧。
从Stream 1到Stream 3的流API比较
Node Stream流模块是用来处理数据流的强大模块,流API不断在改进,Stream 1引入了推流push-stream允许开发者有效地使用数据,Stream 2在推流基础上加入拉流pull-stream,这两种风格不能一起使用,Stream 3以一种灵活的方式解决了这个问题,允许同样的流既能push推又能拉pull,Stream3将在Node v0.11/v0.12和io.js中适用。
Stream 1推流
在最初的流实现中,每次当有数据可用时,都有一个数据事件发生,开发者可以使用pause()和resume()来控制流,调用pause()将引起底层停止发送数据事件的发生。
// node 0.8
var fs = require(‘fs’);
var stream = fs.createReadStream(‘readme.txt’);
stream.setEncoding(‘utf8’);
stream.pause();
// 一秒后再开始流Resume the stream in 1 second
setTimeout(stream.resume.bind(stream), 1000);
var data = ”;
stream.on(‘data’, function(chunk) {
data += chunk;
})
stream.on(‘end’, function() {
// 流终点到达 End of the stream has been reached and no more data can be read
console.log(‘Data length: %d’, data.length);
});
> node test.js
Data length: 1506
不管怎样,Stream 1有一些问题:
- 暂停pause() 方法并不暂停,它只是建议advisory-only.
- 无论你是否准备好,’数据’ 事件就立即来了
- 没有办法消费使用指定数量的字节,然后将剩余的交给程序其他部分来处理。
Stream 2拉流
Node 0.10引入了Streams 2 API,增加了Pull拉方式,也就是从数据流读取时可以采取拉方式,这样解决了以前的问题,流总是从暂停状态开始,通过read(numBytes) API读取,此外,当数据可用时,一个可读的事件将被发射。
// node 0.10 – pull stream, readable event example
var fs = require(‘fs’);
var stream = fs.createReadStream(‘readme.txt’);
stream.setEncoding(‘utf8’);
//不需要使用stream.pause();暂停流
var data = ”;
stream.on(‘readable’, function() {
var chunk;
while(chunk = stream.read()) {
data += chunk;
}
});
stream.on(‘end’, function() {
//流终点到达 End of the stream has been reached and no more data can be read
console.log(‘Data length: %d’, data.length);
});
> node test.js
Data length: 1506
原来Stream 1读数据的推模型还是可以使用,能够使用一个数据事件处理器来实现,增加一个数据事件处理器在un-pausing时有副作用。
// node 0.10 – push stream, data event example
var fs = require(‘fs’);
var stream = fs.createReadStream(‘readme.txt’);
stream.setEncoding(‘utf8’);
stream.pause();
//一秒后重新开始流 Resume the stream in 1 second
setTimeout(stream.resume.bind(stream), 1000);
var data = ”;
stream.on(‘data’, function(chunk) {
data += chunk;
})
stream.on(‘end’, function() {
// End of the stream has been reached and no more data can be read
console.log(‘Data length: %d’, data.length);
});
> node test.js
Data length: 1506
但是拉Pull和Push推不能混合在一起使用
Stream 3混合流
在io.js的1.0.1中,我们有一个混合流的实现,缺省默认流还是可以被暂停,增加数据事件处理器还是可以auto-unpause自动取消暂停流,如果我们暂停流,然后使用read()方法,它将发射一个相应的数据事件。
// node 0.11+, io.js 1.0.1
var fs = require(‘fs’);
var stream = fs.createReadStream(‘readme.txt’);
stream.setEncoding(‘utf8’);
stream.pause();
var pulledData = ”;
var pushedData = ”;
stream.on(‘readable’, function() {
var chunk;
while(chunk = stream.read()) {
pulledData += chunk;
}
});
stream.on(‘data’, function(chunk) {
pushedData += chunk;
});
stream.on(‘end’, function() {
// End of the stream has been reached and no more data can be read
console.log(‘Pulled data length: %d’, pulledData.length);
console.log(‘Pushed data length: %d’, pushedData.length);
});
> node test.js
Pulled data length: 1506
Pushed data length: 1506