NodeJs Stream的整理總結 (二) --雙工流Duplex和Transform

辰辰沉沉大辰沉發表於2018-04-29

對於流我其實並沒有很複雜的操作經驗,文章只是先把要點錄下來,以後有了更深的思考可以在此基礎上新增更多的內容。

這篇文章我認為對初步理解雙工流很有幫助:

NodeJS Stream 五:雙工流

本質上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&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。

相關文章