相關推薦:《node js教學》
#雙工流就是同時實作了Readable 和Writable 的串流,也就是可以作為上游生產數據,又可以作為下游消費數據,這樣可以處於數據流動管道的中間部分,即
rs.pipe(rws1).pipe(rws2).pipe(rws3).pipe(ws);
在NodeJS 中雙工流常用的有兩種
Duplex
Transform
實作Duplex
和Readable、Writable 實作方法類似,實作Duplex 流非常簡單,但Duplex 同時實作了Readable 和Writable, NodeJS 不支援多繼承,所以我們需要繼承Duplex 類別
繼承Duplex 類別
實作_read() 方法
實作_write() 方法
read()、write() 方法的實作不會陌生,因為和Readable、Writable 完全一樣。
const Duplex = require('stream').Duplex; const myDuplex = new Duplex({ read(size) { // ... }, write(chunk, encoding, callback) { // ... } });
建構子參數
Duplex 實例內同時包含可讀流和可寫流,在實例化Duplex 類別的時候可以傳遞幾個參數
小範例
了解了Readable 和Writable 之後看Duplex 很簡單,直接用一個官網的例子const Duplex = require('stream').Duplex; const kSource = Symbol('source'); class MyDuplex extends Duplex { constructor(source, options) { super(options); this[kSource] = source; } _write(chunk, encoding, callback) { // The underlying source only deals with strings if (Buffer.isBuffer(chunk)) chunk = chunk.toString(); this[kSource].writeSomeData(chunk); callback(); } _read(size) { this[kSource].fetchSomeData(size, (data, encoding) => { this.push(Buffer.from(data, encoding)); }); } }
實作Tranform
Tranform 類別內部繼承了Duplex 並實作了writable.write() 和readable._read() 方法,我們想自訂一個Transform 流,只需要在 _transform() 方法內部可以調用 this.push(data) 生產數據,交給可寫流,也可以不調用,意味著輸入不會產生輸出。
當資料處理完了必須呼叫callback(err, data) ,第一個參數用來傳遞錯誤訊息,第二個參數可以省略,如果被傳入了,效果和this.push(data)一樣
transform.prototype._transform = function (data, encoding, callback) { this.push(data); callback(); }; transform.prototype._transform = function (data, encoding, callback) { callback(null, data); };
有些時候,transform 操作可能需要在流的最後多寫入可寫流一些資料。例如, Zlib流會儲存一些內部狀態,以便最佳化壓縮輸出。在這種情況下,可以使用_flush()方法,它會在所有寫入資料被消費、觸發 'end'之前被呼叫。
Transform 事件
對比
看兩個簡單的例子就能直觀了解 Duplex 和 Transform 的差異
TCP socketnet 模块可以用来创建 socket,socket 在 NodeJS 中是一个典型的 Duplex,看一个 TCP 客户端的例子 可以看到 client 就是一个 Duplex,可写流用于向服务器发送消息,可读流用于接受服务器消息,两个流内的数据并没有直接的关系。 gulp gulp 非常擅长处理代码本地构建流程,看一段官网的示例代码 其中 jada() 和 minify() 就是典型的 Transform,处理流程大概是 可以看出来,jade() 和 minify() 都是对输入数据做了些特殊处理,然后交给了输出数据。 这样简单的对比就能看出 Duplex 和 Transform 的区别,在平时实用的时候,当一个流同事面向生产者和消费者服务的时候我们会选择 Duplex,当只是对数据做一些转换工作的时候我们便会选择使用 Tranform。 更多编程相关知识,请访问:编程学习网站!!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('已与服务器断开连接');
});
gulp.src('client/templates/*.jade')
.pipe(jade())
.pipe(minify())
.pipe(gulp.dest('build/minified_templates'));
.jade 模板文件 -> jada() -> html 文件 -> minify -> 压缩后的 html
以上是淺談Nodejs中的雙工流的詳細內容。更多資訊請關注PHP中文網其他相關文章!