站長資訊網
        最全最豐富的資訊網站

        深入理解Node.js 中的流(Stream)

        深入理解Node.js 中的流(Stream)

        Node.js 中的流(Stream)是出了名的難用甚至是難以理解。【視頻教程推薦:nodejs視頻教程 】

        用 Dominic Tarr 的話來說:“流是 Node 中最好的,也是最容易被誤解的想法?!奔词故?Redux 的創建者和 React.js 的核心團隊成員 Dan Abramov 也害怕 Node 流。

        深入理解Node.js 中的流(Stream)深入理解Node.js 中的流(Stream)

        本文將幫助你了解流以及如何使用。不要害怕,你完全可以把它搞清楚!

        什么是流(Stream)?

        流(Stream)是為 Node.js 應用提供動力的基本概念之一。它們是數據處理方法,用于將輸入的數據順序讀取或把數據寫入輸出。

        流是一種以有效方式處理讀寫文件、網絡通信或任何類型的端到端信息交換的方式。

        流的處理方式非常獨特,流不是像傳統方式那樣將文件一次全部讀取到存儲器中,而是逐段讀取數據塊并處理數據的內容,不將其全部保留在內存中。

        這種方式使流在處理大量數據時非常強大,例如,文件的大小可能大于可用的內存空間,從而無法將整個文件讀入內存進行處理。那是流的用武之地!

        既能用流來處理較小的數據塊,也可以讀取較大的文件。

        以 YouTube 或 Netflix 之類的“流媒體”服務為例:這些服務不會讓你你立即下載視頻和音頻文件。取而代之的是,你的瀏覽器以連續的塊流形式接收視頻,從而使接收者幾乎可以立即開始觀看和收聽。

        但是,流不僅涉及處理媒體和大數據。它們還在代碼中賦予了我們“可組合性”的力量??紤]可組合性的設計意味著能夠以某種方式組合多個組件以產生相同類型的結果。在 Node.js 中,可以通過流在其他較小的代碼段中傳遞數據,從而組成功能強大的代碼段。

        為什么使用流?

        與其他數據處理方法相比,流基本上具有兩個主要優點:

        1. 內存效率:你無需事先把大量數據加載到內存中即可進行處理
        2. 時間效率:得到數據后立即開始處所需的時間大大減少,不必等到整個有效數據全部發送完畢才開始處理

        Node.js 中有 4 種流:

        1. 可寫流:可以向其中寫入數據的流。例如,fs.createWriteStream() 使我們可以使用流將數據寫入文件。
        2. 可讀流:可從中讀取數據的流。例如:fs.createReadStream() 讓我們讀取文件的內容。
        3. 雙工流(可讀寫的流):可讀和可寫的流。例如,net.Socket
        4. Transform:可在寫入和讀取時修改或轉換數據。例如在文件壓縮的情況下,你可以在文件中寫入壓縮數據,也可以從文件中讀取解壓縮的數據。

        如果你已經使用過 Node.js,則可能遇到過流。例如在基于 Node.js 的 HTTP 服務器中,request 是可讀流,而 response 是可寫流。你可能用過 fs 模塊,該模塊可讓你用可讀和可寫文件流。每當使用 Express 時,你都在使用流與客戶端進行交互,而且由于 TCP 套接字、TLS棧和其他連接都基于 Node.js,所以在每個可以使用的數據庫連接驅動的程序中使用流。

        實例

        如何創建可讀流?

        首先需要可讀性流,然后將其初始化。

        const Stream = require('stream') const readableStream = new Stream.Readable()

        現在,流已初始化,可以向其發送數據了:

        readableStream.push('ping!') readableStream.push('pong!')

        異步迭代器

        強烈建議在使用流時配合異步迭代器(async iterator)。根據 Axel Rauschmayer 博士的說法,異步迭代是一種用于異步檢索數據容器內容的協議(這意味著當前“任務”可以在檢索項目之前被暫停)。另外必須提及的是,流異步迭代器實現使用內部的 readable 事件。

        從可讀流中讀取時,可以使用異步迭代器:

        import * as fs from 'fs';  async function logChunks(readable) {   for await (const chunk of readable) {     console.log(chunk);   } }  const readable = fs.createReadStream(   'tmp/test.txt', {encoding: 'utf8'}); logChunks(readable);  // Output: // 'This is a test!n'

        也可以用字符串收集可讀流的內容:

        import {Readable} from 'stream';  async function readableToString2(readable) {   let result = '';   for await (const chunk of readable) {     result += chunk;   }   return result; }  const readable = Readable.from('Good morning!', {encoding: 'utf8'}); assert.equal(await readableToString2(readable), 'Good morning!');

        注意,在這種情況下必須使用異步函數,因為我們想返回 Promise。

        請切記不要將異步功能與 EventEmitter 混合使用,因為當前在事件處理程序中發出拒絕時,無法捕獲拒絕,從而導致難以跟蹤錯誤和內存泄漏。目前的最佳實踐是始終將異步函數的內容包裝在 try/catch 塊中并處理錯誤,但這很容易出錯。 這個 pull request 旨在解決一旦其落在 Node 核心上產生的問題。

        要了解有關異步迭代的 Node.js 流的

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 国产香蕉国产精品偷在线| 亚洲精品岛国片在线观看| 亚洲国产精品成人一区| 一区二区精品在线| HEYZO无码综合国产精品227| 韩国三级中文字幕hd久久精品| 国产精品1024香蕉在线观看| 亚洲国产精品福利片在线观看 | 国产精品午夜久久| 精品免费视在线观看| 精品人妻无码一区二区色欲产成人| 无码国产亚洲日韩国精品视频一区二区三区| 国产精品九九九| 日韩精品免费在线视频| 99在线精品视频| 熟女精品视频一区二区三区| 亚洲国产精品人人做人人爽 | 国产精品亚洲片夜色在线| 国产精品久久久亚洲| 精品无码一区二区三区爱欲九九 | 3D动漫精品一区二区三区| 久久精品无码专区免费青青 | 久久99精品久久久久久噜噜| 成人一区二区三区精品| 亚洲国产精品久久| 亚洲国产综合91精品麻豆| 久久精品男人影院| 四虎影视884a精品国产四虎 | 亚洲av午夜国产精品无码中文字 | 国产午夜精品一区二区三区小说| 国产精品成人不卡在线观看| 国产亚洲色婷婷久久99精品| 亚洲精品成人片在线播放| 日韩美女18网站久久精品| 香港三级精品三级在线专区 | 国产精品成人免费观看| 99精品视频在线观看婷| 国产精品青青在线观看爽香蕉| 国产一区精品| 久久久久久国产精品免费免费 | 欧美精品色精品一区二区三区|