中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

Nodejs中雙工流指的是什么

這篇文章給大家分享的是有關(guān)Nodejs中雙工流指的是什么的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。

創(chuàng)新互聯(lián)公司是一家專注于網(wǎng)站設(shè)計制作、網(wǎng)站制作與策劃設(shè)計,定陶網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10多年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:定陶等地區(qū)。定陶做網(wǎng)站價格咨詢:18980820575

雙工流就是同時實現(xiàn)了 Readable 和 Writable 的流,即可以作為上游生產(chǎn)數(shù)據(jù),又可以作為下游消費數(shù)據(jù),這樣可以處于數(shù)據(jù)流動管道的中間部分,即

 rs.pipe(rws1).pipe(rws2).pipe(rws3).pipe(ws);

在 NodeJS 中雙工流常用的有兩種

  • Duplex

  • Transform

Duplex

實現(xiàn) Duplex

和 Readable、Writable 實現(xiàn)方法類似,實現(xiàn) Duplex 流非常簡單,但 Duplex 同時實現(xiàn)了 Readable 和 Writable, NodeJS 不支持多繼承,所以我們需要繼承 Duplex 類

  • 繼承 Duplex 類

  • 實現(xiàn) _read() 方法

  • 實現(xiàn) _write() 方法

相信大家對 read()、write() 方法的實現(xiàn)不會陌生,因為和 Readable、Writable 完全一樣。

const Duplex = require('stream').Duplex;

const myDuplex = new Duplex({
  read(size) {
    // ...
  },
  write(chunk, encoding, callback) {
    // ...
  }
});

構(gòu)造函數(shù)參數(shù)

Duplex 實例內(nèi)同時包含可讀流和可寫流,在實例化 Duplex 類的時候可以傳遞幾個參數(shù)

  • readableObjectMode
  • writableObjectMode
  • allowHalfOpen

小例子

了解了 Readable 和 Writable 之后看 Duplex 非常簡單,直接用一個官網(wǎng)的例子

 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));
    });
  }
}

當(dāng)然這是不能執(zhí)行的偽代碼,但是 Duplex 的作用可見一斑,進(jìn)可以生產(chǎn)數(shù)據(jù),又可以消費數(shù)據(jù),所以才可以處于數(shù)據(jù)流動管道的中間環(huán)節(jié),常見的 Duplex 流有

  • Tcp Scoket
  • Zlib
  • Crypto

Transform

Transform 同樣是雙工流,看起來和 Duplex 重復(fù)了,但兩者有一個重要的區(qū)別:Duplex 雖然同事具備可讀流和可寫流,但兩者是相對獨立的;Transform 的可讀流的數(shù)據(jù)會經(jīng)過一定的處理過程自動進(jìn)入可寫流。

雖然會從可讀流進(jìn)入可寫流,但并不意味這兩者的數(shù)據(jù)量相同,上面說的一定的處理邏輯會決定如果 tranform 可讀流,然后放入可寫流,transform 原義即為轉(zhuǎn)變,很貼切的描述了 Transform 流作用。

我們最常見的壓縮、解壓縮用的 zlib 即為 Transform 流,壓縮、解壓前后的數(shù)據(jù)量明顯不同,兒流的作用就是輸入一個 zip 包,輸入一個解壓文件或反過來。我們平時用的大部分雙工流都是 Transform。

實現(xiàn) Tranform

Tranform 類內(nèi)部繼承了 Duplex 并實現(xiàn)了 writable.write() 和 readable._read() 方法,我們想自定義一個 Transform 流,只需要

  • 繼承 Transform 類

  • 實現(xiàn) _transform() 方法

  • 實現(xiàn) _flush() 方法(可以不實現(xiàn))

_transform(chunk, encoding, callback) 方法用來接收數(shù)據(jù),并產(chǎn)生輸出,參數(shù)我們已經(jīng)很熟悉了,和 Writable 一樣, chunk 默認(rèn)是 Buffer,除非 decodeStrings 被設(shè)置為 false。

在 _transform() 方法內(nèi)部可以調(diào)用 this.push(data) 生產(chǎn)數(shù)據(jù),交給可寫流,也可以不調(diào)用,意味著輸入不會產(chǎn)生輸出。

當(dāng)數(shù)據(jù)處理完了必須調(diào)用 callback(err, data)  ,第一個參數(shù)用于傳遞錯誤信息,第二個參數(shù)可以省略,如果被傳入了,效果和 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 操作可能需要在流的最后多寫入可寫流一些數(shù)據(jù)。例如, Zlib流會存儲一些內(nèi)部狀態(tài),以便優(yōu)化壓縮輸出。在這種情況下,可以使用_flush()方法,它會在所有寫入數(shù)據(jù)被消費、觸發(fā) 'end'之前被調(diào)用。

Transform 事件

Transform 流有兩個常用的事件

  • 來自 Writable 的 finish

  • 來自 Readable 的 end

當(dāng)調(diào)用 transform.end() 并且數(shù)據(jù)被 _transform() 處理完后會觸發(fā) finish,調(diào)用_flush后,所有的數(shù)據(jù)輸出完畢,觸發(fā)end事件。

對比

了解了 Readable 和 Writable 之后,理解雙工流十分自然,但兩者的區(qū)別會讓一些初學(xué)者困惑,簡單的區(qū)分:Duplex 的可讀流和可寫流之間并沒有直接關(guān)系,Transform 中可讀流的數(shù)據(jù)會經(jīng)過處理后自動放入可寫流中。

看兩個簡單的例子就能直觀了解到 Duplex 和 Transform 的區(qū)別

TCP socket

net 模塊可以用來創(chuàng)建 socket,socket 在 NodeJS 中是一個典型的 Duplex,看一個 TCP 客戶端的例子

var net = require('net');

//創(chuàng)建客戶端
var client = net.connect({port: 1234}, function() {
    console.log('已連接到服務(wù)器');
    client.write('Hi!');
});

//data事件監(jiān)聽。收到數(shù)據(jù)后,斷開連接
client.on('data', function(data) {
    console.log(data.toString());
    client.end();
});

//end事件監(jiān)聽,斷開連接時會被觸發(fā)
client.on('end', function() {
    console.log('已與服務(wù)器斷開連接');
});

可以看到 client 就是一個 Duplex,可寫流用于向服務(wù)器發(fā)送消息,可讀流用于接受服務(wù)器消息,兩個流內(nèi)的數(shù)據(jù)并沒有直接的關(guān)系。

gulp

gulp 非常擅長處理代碼本地構(gòu)建流程,看一段官網(wǎng)的示例代碼

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() 都是對輸入數(shù)據(jù)做了些特殊處理,然后交給了輸出數(shù)據(jù)。

這樣簡單的對比就能看出 Duplex 和 Transform 的區(qū)別,在平時實用的時候,當(dāng)一個流同事面向生產(chǎn)者和消費者服務(wù)的時候我們會選擇 Duplex,當(dāng)只是對數(shù)據(jù)做一些轉(zhuǎn)換工作的時候我們便會選擇使用 Tranform。

感謝各位的閱讀!關(guān)于Nodejs中雙工流指的是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

當(dāng)前題目:Nodejs中雙工流指的是什么
網(wǎng)址分享:http://www.rwnh.cn/article38/gsphpp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃網(wǎng)站設(shè)計公司、微信公眾號外貿(mào)建站、App開發(fā)定制開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化
什邡市| 龙岩市| 沛县| 瓦房店市| 河南省| 宁蒗| 独山县| 洪江市| 沭阳县| 海宁市| 罗江县| 凤冈县| 石屏县| 镶黄旗| 甘孜县| 靖宇县| 茂名市| 洛川县| 秭归县| 宁蒗| 洪洞县| 黄浦区| 文登市| 城固县| 石阡县| 河北区| 阳原县| 即墨市| 新干县| 丹阳市| 天门市| 泾川县| 宁强县| 惠东县| 周宁县| 醴陵市| 达孜县| 沐川县| 兴宁市| 东台市| 固原市|