NodeJs Stream的整理总结 (二) --双工流Duplex和Transform
对于流我其实并没有很复杂的操作经验,文章只是先把要点录下来,以后有了更深的思考可以在此基础上添加更多的内容。
这篇文章我认为对初步理解双工流很有帮助:
本质上Transform是Duplex的一种,官方文档的描述也明确指出了这一点:
Duplex流定义
Duplex streams are streams that implement both the Readable and Writable interfaces.
Examples of Duplex streams include:
- TCP sockets
- zlib streams
- crypto streams
Transfrom流定义
Transform streams are Duplex streams where the output is in some way related to the input. Like all Duplex streams, Transform streams implement both the Readable and Writable interfaces.
Examples of Transform streams include:
- zlib streams
-
crypto streams
通过上面的定义,我们可以用下图来表示Duplex和Transform流的关系:
自定义Duplex
- 继承 Duplex 类
- 实现 _read() 方法
- 实现 _write() 方法
自定义Transform
stream.Transform类最初继承自stream.Duplex,并且实现了它自己版本的writable._write()和readable._read()方法。
一般地,变换流必须实现transform._transform() 方法; 而transform._flush() 方法是非必须的。
Duplex和Transform实例对比:Tcp Socket vs Gulp
这里直接引用篇头参考文章的例子了:
Tcp Socket
var net = require('net');
//创建客户端
var client = net.connect({port: 1234}, function() {
console.log('已连接到服务器');
client.write('Hi!');
});
//data事件监听。收到数据后,断开连接
client.on('data', function(data) {
console.log(data.toString());
client.end();
});
//end事件监听,断开连接时会被触发
client.on('end', function() {
console.log('已与服务器断开连接');
});
可以看到 client 就是一个 Duplex,可写流用于向服务器发送消息,可读流用于接受服务器消息,两个流内的数据并没有直接的关系。
Gulp
gulp.src('client/templates/*.jade')
.pipe(jade())
.pipe(minify())
.pipe(gulp.dest('build/minified_templates'));
其中 jada() 和 minify() 就是典型的 Transform,处理流程大概是:
.jade 模板文件 -> jada() -> html 文件 -> minify -> 压缩后的 html
可以看出来,jade() 和 minify() 都是对输入数据做了些特殊处理,然后交给了输出数据。
这样简单的对比就能看出 Duplex 和 Transform 的区别,在平时实用的时候,当一个流同事面向生产者和消费者服务的时候我们会选择 Duplex,当只是对数据做一些转换工作的时候我们便会选择使用 Tranform。