国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Node.js 中流操作實(shí)踐

chaos_G / 3018人閱讀

摘要:事件的觸發(fā)頻次同樣是由實(shí)現(xiàn)者決定,譬如在進(jìn)行文件讀取時(shí),可能每行都會(huì)觸發(fā)一次而在請(qǐng)求處理時(shí),可能數(shù)的數(shù)據(jù)才會(huì)觸發(fā)一次。如果有參數(shù)傳入,它會(huì)讓可讀流停止流向某個(gè)特定的目的地,否則,它會(huì)移除所有目的地。

本文節(jié)選自 Node.js CheatSheet | Node.js 語(yǔ)法基礎(chǔ)、框架使用與實(shí)踐技巧,也可以閱讀 JavaScript CheatSheet 或者 現(xiàn)代 Web 開(kāi)發(fā)基礎(chǔ)與工程實(shí)踐 了解更多 JavaScript/Node.js 的實(shí)際應(yīng)用。

Stream 是 Node.js 中的基礎(chǔ)概念,類似于 EventEmitter,專注于 IO 管道中事件驅(qū)動(dòng)的數(shù)據(jù)處理方式;類比于數(shù)組或者映射,Stream 也是數(shù)據(jù)的集合,只不過(guò)其代表了不一定正在內(nèi)存中的數(shù)據(jù)。。Node.js 的 Stream 分為以下類型:

Readable Stream: 可讀流,數(shù)據(jù)的產(chǎn)生者,譬如 process.stdin

Writable Stream: 可寫流,數(shù)據(jù)的消費(fèi)者,譬如 process.stdout 或者 process.stderr

Duplex Stream: 雙向流,即可讀也可寫

Transform Stream: 轉(zhuǎn)化流,數(shù)據(jù)的轉(zhuǎn)化者

Stream 本身提供了一套接口規(guī)范,很多 Node.js 中的內(nèi)建模塊都遵循了該規(guī)范,譬如著名的 fs 模塊,即是使用 Stream 接口來(lái)進(jìn)行文件讀寫;同樣的,每個(gè) HTTP 請(qǐng)求是可讀流,而 HTTP 響應(yīng)則是可寫流。

Readable Stream
const stream = require("stream");
const fs = require("fs");

const readableStream = fs.createReadStream(process.argv[2], {
  encoding: "utf8"
});

// 手動(dòng)設(shè)置流數(shù)據(jù)編碼
// readableStream.setEncoding("utf8");

let wordCount = 0;

readableStream.on("data", function(data) {
  wordCount += data.split(/s{1,}/).length;
});

readableStream.on("end", function() {
  // Don"t count the end of the file.
  console.log("%d %s", --wordCount, process.argv[2]);
});

當(dāng)我們創(chuàng)建某個(gè)可讀流時(shí),其還并未開(kāi)始進(jìn)行數(shù)據(jù)流動(dòng);添加了 data 的事件監(jiān)聽(tīng)器,它才會(huì)變成流動(dòng)態(tài)的。在這之后,它就會(huì)讀取一小塊數(shù)據(jù),然后傳到我們的回調(diào)函數(shù)里面。 data 事件的觸發(fā)頻次同樣是由實(shí)現(xiàn)者決定,譬如在進(jìn)行文件讀取時(shí),可能每行都會(huì)觸發(fā)一次;而在 HTTP 請(qǐng)求處理時(shí),可能數(shù) KB 的數(shù)據(jù)才會(huì)觸發(fā)一次。可以參考 nodejs/readable-stream/_stream_readable 中的相關(guān)實(shí)現(xiàn),發(fā)現(xiàn) on 函數(shù)會(huì)觸發(fā) resume 方法,該方法又會(huì)調(diào)用 flow 函數(shù)進(jìn)行流讀取:

// function on
if (ev === "data") {
  // Start flowing on next tick if stream isn"t explicitly paused
  if (this._readableState.flowing !== false) this.resume();
}
...
// function flow
while (state.flowing && stream.read() !== null) {}

我們還可以監(jiān)聽(tīng) readable 事件,然后手動(dòng)地進(jìn)行數(shù)據(jù)讀取:

let data = "";
let chunk;
readableStream.on("readable", function() {
  while ((chunk = readableStream.read()) != null) {
    data += chunk;
  }
});
readableStream.on("end", function() {
  console.log(data);
});

Readable Stream 還包括如下常用的方法:

Readable.pause(): 這個(gè)方法會(huì)暫停流的流動(dòng)。換句話說(shuō)就是它不會(huì)再觸發(fā) data 事件。

Readable.resume(): 這個(gè)方法和上面的相反,會(huì)讓暫停流恢復(fù)流動(dòng)。

Readable.unpipe(): 這個(gè)方法會(huì)把目的地移除。如果有參數(shù)傳入,它會(huì)讓可讀流停止流向某個(gè)特定的目的地,否則,它會(huì)移除所有目的地。

在日常開(kāi)發(fā)中,我們可以用 stream-wormhole 來(lái)模擬消耗可讀流:

sendToWormhole(readStream, true);
Writable Stream
readableStream.on("data", function(chunk) {
  writableStream.write(chunk);
});

writableStream.end();

當(dāng) end() 被調(diào)用時(shí),所有數(shù)據(jù)會(huì)被寫入,然后流會(huì)觸發(fā)一個(gè) finish 事件。注意在調(diào)用 end() 之后,你就不能再往可寫流中寫入數(shù)據(jù)了。

const { Writable } = require("stream");

const outStream = new Writable({
  write(chunk, encoding, callback) {
    console.log(chunk.toString());
    callback();
  }
});

process.stdin.pipe(outStream);

Writable Stream 中同樣包含一些與 Readable Stream 相關(guān)的重要事件:

error: 在寫入或鏈接發(fā)生錯(cuò)誤時(shí)觸發(fā)

pipe: 當(dāng)可讀流鏈接到可寫流時(shí),這個(gè)事件會(huì)觸發(fā)

unpipe: 在可讀流調(diào)用 unpipe 時(shí)會(huì)觸發(fā)

Pipe | 管道
const fs = require("fs");

const inputFile = fs.createReadStream("REALLY_BIG_FILE.x");
const outputFile = fs.createWriteStream("REALLY_BIG_FILE_DEST.x");

// 當(dāng)建立管道時(shí),才發(fā)生了流的流動(dòng)
inputFile.pipe(outputFile);

多個(gè)管道順序調(diào)用,即是構(gòu)建了鏈接(Chaining):

const fs = require("fs");
const zlib = require("zlib");
fs.createReadStream("input.txt.gz")
  .pipe(zlib.createGunzip())
  .pipe(fs.createWriteStream("output.txt"));

管道也常用于 Web 服務(wù)器中的文件處理,以 Egg.js 中的應(yīng)用為例,我們可以從 Context 中獲取到文件流并將其傳入到可寫文件流中:

           
               
                                           
                       
                 

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/97600.html

相關(guān)文章

  • Node.js中流的使用

    摘要:流是基于事件的用于管理和處理數(shù)據(jù)而且有不錯(cuò)的效率借助事件和非阻塞庫(kù)流模塊允許在其可用的時(shí)候動(dòng)態(tài)處理在其不需要的時(shí)候釋放掉使用流的好處舉一個(gè)讀取文件的例子使用同步讀取一個(gè)文件程序會(huì)被阻塞所有的數(shù)據(jù)都會(huì)被讀取到內(nèi)存中換用讀取文件程序不會(huì)被阻塞但 流是基于事件的API,用于管理和處理數(shù)據(jù),而且有不錯(cuò)的效率.借助事件和非阻塞I/O庫(kù),流模塊允許在其可用的時(shí)候動(dòng)態(tài)處理,在其不需要的時(shí)候釋放掉. ...

    h9911 評(píng)論0 收藏0
  • 前端每周清單半年盤點(diǎn)之 Node.js

    摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開(kāi)發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開(kāi)發(fā)教程工程實(shí)踐深度閱讀開(kāi)源項(xiàng)目巔峰人生等欄目。對(duì)該漏洞的綜合評(píng)級(jí)為高危。目前,相關(guān)利用方式已經(jīng)在互聯(lián)網(wǎng)上公開(kāi),近期出現(xiàn)攻擊嘗試爆發(fā)的可能。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開(kāi)發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開(kāi)發(fā)教程、工程實(shí)踐、深度閱讀、開(kāi)源項(xiàng)目、巔峰人生等欄目。歡...

    kid143 評(píng)論0 收藏0
  • 【全文】狼叔:如何正確的學(xué)習(xí)Node.js

    摘要:感謝大神的免費(fèi)的計(jì)算機(jī)編程類中文書籍收錄并推薦地址,以后在倉(cāng)庫(kù)里更新地址,聲音版全文狼叔如何正確的學(xué)習(xí)簡(jiǎn)介現(xiàn)在,越來(lái)越多的科技公司和開(kāi)發(fā)者開(kāi)始使用開(kāi)發(fā)各種應(yīng)用。 說(shuō)明 2017-12-14 我發(fā)了一篇文章《沒(méi)用過(guò)Node.js,就別瞎逼逼》是因?yàn)橛腥嗽谥跎虾贜ode.js。那篇文章的反響還是相當(dāng)不錯(cuò)的,甚至連著名的hax賀老都很認(rèn)同,下班時(shí)讀那篇文章,竟然坐車的還坐過(guò)站了。大家可以很...

    Edison 評(píng)論0 收藏0
  • 【全文】狼叔:如何正確的學(xué)習(xí)Node.js

    摘要:感謝大神的免費(fèi)的計(jì)算機(jī)編程類中文書籍收錄并推薦地址,以后在倉(cāng)庫(kù)里更新地址,聲音版全文狼叔如何正確的學(xué)習(xí)簡(jiǎn)介現(xiàn)在,越來(lái)越多的科技公司和開(kāi)發(fā)者開(kāi)始使用開(kāi)發(fā)各種應(yīng)用。 說(shuō)明 2017-12-14 我發(fā)了一篇文章《沒(méi)用過(guò)Node.js,就別瞎逼逼》是因?yàn)橛腥嗽谥跎虾贜ode.js。那篇文章的反響還是相當(dāng)不錯(cuò)的,甚至連著名的hax賀老都很認(rèn)同,下班時(shí)讀那篇文章,竟然坐車的還坐過(guò)站了。大家可以很...

    fengxiuping 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<