摘要:事件的觸發頻次同樣是由實現者決定,譬如在進行文件讀取時,可能每行都會觸發一次而在請求處理時,可能數的數據才會觸發一次。如果有參數傳入,它會讓可讀流停止流向某個特定的目的地,否則,它會移除所有目的地。
本文節選自 Node.js CheatSheet | Node.js 語法基礎、框架使用與實踐技巧,也可以閱讀 JavaScript CheatSheet 或者 現代 Web 開發基礎與工程實踐 了解更多 JavaScript/Node.js 的實際應用。
Stream 是 Node.js 中的基礎概念,類似于 EventEmitter,專注于 IO 管道中事件驅動的數據處理方式;類比于數組或者映射,Stream 也是數據的集合,只不過其代表了不一定正在內存中的數據。。Node.js 的 Stream 分為以下類型:
Readable Stream: 可讀流,數據的產生者,譬如 process.stdin
Writable Stream: 可寫流,數據的消費者,譬如 process.stdout 或者 process.stderr
Duplex Stream: 雙向流,即可讀也可寫
Transform Stream: 轉化流,數據的轉化者
Stream 本身提供了一套接口規范,很多 Node.js 中的內建模塊都遵循了該規范,譬如著名的 fs 模塊,即是使用 Stream 接口來進行文件讀寫;同樣的,每個 HTTP 請求是可讀流,而 HTTP 響應則是可寫流。
Readable Streamconst stream = require("stream"); const fs = require("fs"); const readableStream = fs.createReadStream(process.argv[2], { encoding: "utf8" }); // 手動設置流數據編碼 // 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]); });
當我們創建某個可讀流時,其還并未開始進行數據流動;添加了 data 的事件監聽器,它才會變成流動態的。在這之后,它就會讀取一小塊數據,然后傳到我們的回調函數里面。 data 事件的觸發頻次同樣是由實現者決定,譬如在進行文件讀取時,可能每行都會觸發一次;而在 HTTP 請求處理時,可能數 KB 的數據才會觸發一次。可以參考 nodejs/readable-stream/_stream_readable 中的相關實現,發現 on 函數會觸發 resume 方法,該方法又會調用 flow 函數進行流讀取:
// 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) {}
我們還可以監聽 readable 事件,然后手動地進行數據讀取:
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(): 這個方法會暫停流的流動。換句話說就是它不會再觸發 data 事件。
Readable.resume(): 這個方法和上面的相反,會讓暫停流恢復流動。
Readable.unpipe(): 這個方法會把目的地移除。如果有參數傳入,它會讓可讀流停止流向某個特定的目的地,否則,它會移除所有目的地。
在日常開發中,我們可以用 stream-wormhole 來模擬消耗可讀流:
sendToWormhole(readStream, true);Writable Stream
readableStream.on("data", function(chunk) { writableStream.write(chunk); }); writableStream.end();
當 end() 被調用時,所有數據會被寫入,然后流會觸發一個 finish 事件。注意在調用 end() 之后,你就不能再往可寫流中寫入數據了。
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 相關的重要事件:
error: 在寫入或鏈接發生錯誤時觸發
pipe: 當可讀流鏈接到可寫流時,這個事件會觸發
unpipe: 在可讀流調用 unpipe 時會觸發
Pipe | 管道const fs = require("fs"); const inputFile = fs.createReadStream("REALLY_BIG_FILE.x"); const outputFile = fs.createWriteStream("REALLY_BIG_FILE_DEST.x"); // 當建立管道時,才發生了流的流動 inputFile.pipe(outputFile);
多個管道順序調用,即是構建了鏈接(Chaining):
const fs = require("fs"); const zlib = require("zlib"); fs.createReadStream("input.txt.gz") .pipe(zlib.createGunzip()) .pipe(fs.createWriteStream("output.txt"));
管道也常用于 Web 服務器中的文件處理,以 Egg.js 中的應用為例,我們可以從 Context 中獲取到文件流并將其傳入到可寫文件流中:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/97600.html
摘要:流是基于事件的用于管理和處理數據而且有不錯的效率借助事件和非阻塞庫流模塊允許在其可用的時候動態處理在其不需要的時候釋放掉使用流的好處舉一個讀取文件的例子使用同步讀取一個文件程序會被阻塞所有的數據都會被讀取到內存中換用讀取文件程序不會被阻塞但 流是基于事件的API,用于管理和處理數據,而且有不錯的效率.借助事件和非阻塞I/O庫,流模塊允許在其可用的時候動態處理,在其不需要的時候釋放掉. ...
摘要:前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點分為新聞熱點開發教程工程實踐深度閱讀開源項目巔峰人生等欄目。對該漏洞的綜合評級為高危。目前,相關利用方式已經在互聯網上公開,近期出現攻擊嘗試爆發的可能。 前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點;分為新聞熱點、開發教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡...
摘要:感謝大神的免費的計算機編程類中文書籍收錄并推薦地址,以后在倉庫里更新地址,聲音版全文狼叔如何正確的學習簡介現在,越來越多的科技公司和開發者開始使用開發各種應用。 說明 2017-12-14 我發了一篇文章《沒用過Node.js,就別瞎逼逼》是因為有人在知乎上黑Node.js。那篇文章的反響還是相當不錯的,甚至連著名的hax賀老都很認同,下班時讀那篇文章,竟然坐車的還坐過站了。大家可以很...
摘要:感謝大神的免費的計算機編程類中文書籍收錄并推薦地址,以后在倉庫里更新地址,聲音版全文狼叔如何正確的學習簡介現在,越來越多的科技公司和開發者開始使用開發各種應用。 說明 2017-12-14 我發了一篇文章《沒用過Node.js,就別瞎逼逼》是因為有人在知乎上黑Node.js。那篇文章的反響還是相當不錯的,甚至連著名的hax賀老都很認同,下班時讀那篇文章,竟然坐車的還坐過站了。大家可以很...
閱讀 1641·2021-10-09 09:44
閱讀 2797·2021-10-08 10:04
閱讀 2470·2021-09-26 09:55
閱讀 3848·2021-09-22 10:02
閱讀 3314·2019-08-29 17:08
閱讀 1071·2019-08-29 15:08
閱讀 2960·2019-08-26 13:52
閱讀 3275·2019-08-26 13:34