使用 Streams API 高效處理資料
Streams API 使您能夠訪問透過網路接收的資料流,並在網頁上使用 JavaScript 進行處理。以前,如果您想處理透過網路獲取的資料,您必須先下載整個資源,等待其轉換為您可以處理的格式,然後再開始處理。使用 Streams API,您可以在原始資料到達時使用 JavaScript 進行處理,這使其非常適合處理連續資料來源、即時轉換資料、在收到所需資料時取消流等等。
在本文中,我們將探討 Streams API 的概念、用法和實際應用。我們還將透過一個實際示例,構建一個小應用程式,該應用程式使用該 API 來轉換資料流。
理解 Streams API
Streams API 提供了一種在 JavaScript 中處理流式資料的標準方法。它允許您逐塊處理資料,對於處理 Web 應用程式中的大型資源或即時資料非常高效。您應該瞭解 Streams API 中的這些關鍵概念:
- 資料塊 (Chunks)
-
資料以稱為資料塊的片段順序讀取。一個數據塊可以是一個位元組,也可以是較大的內容,例如特定大小的 型別化陣列。單個流可以包含不同大小和型別的資料塊。
- 背壓
-
API 自動管理背壓,確保快速生產者不會壓倒慢速消費者。這透過內部佇列機制來處理。
- 管道 (Piping)
-
API 提供諸如
pipeThrough()和pipeTo()之類的方法來連線流,從而允許對資料進行鏈式處理。
API 包含以下針對不同型別流的抽象:
ReadableStream-
表示可以從中讀取資料的源。它可以從各種源建立,例如 fetch 響應或檔案輸入。
WritableStream-
表示可以向其中寫入資料的目標。可用於寫入檔案或將資料傳送到伺服器等任務。
TransformStream-
允許在資料從可讀流傳遞到可寫流時修改資料。適用於壓縮或加密等任務。
構建 Node.js 應用程式
首先,請按照我們上一篇文章 在 Vultr 上部署伺服器 部分所述的步驟部署伺服器。接下來,透過 SSH 訪問伺服器終端,併為我們的 Web 應用程式設定專案。
我們將使用 Nano 文字編輯器在伺服器上建立和編輯我們的專案檔案。您可以在 快捷鍵備忘單 中查詢使用 Nano 的幫助。我們還將使用 Uncomplicated Firewall (UFW) 來控制允許進出伺服器的流量。在我們的應用程式中,Node.js 服務於應用程式的索引,並使用 http-server 執行應用程式。像 Python 和 Apache 這樣的伺服器也可以達到類似的效果。我們使用 UFW 啟用埠 8000 的入站流量。
-
建立一個專案目錄,並進入該目錄。
bashmkdir streaming-app && cd streaming-app -
初始化一個 Node.js 專案。
bashnpm init -y -
安裝 HTTP 伺服器。
bashnpm install http-server -
建立一個 HTML 檔案。
bashnano index.html -
將以下程式碼複製並貼上到 index.html 檔案中。
html<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>File Stream Transformer</title> </head> <body> <h1>File Stream Transformer</h1> <button id="loadFileButton">Load and Transform File</button> <br /> <h2>Transformed Content:</h2> <pre id="outputText"></pre> <script src="app.js"></script> </body> </html> -
儲存並退出檔案。
-
在專案目錄中建立一個文字檔案
textfile.txt,並提供一些示例文字。您可以方便地使用 此文字檔案 中的內容。
建立示例 Streams API 應用
-
在 streaming-app 目錄中,建立一個 JavaScript 檔案。
bashnano app.js -
將以下 JavaScript 程式碼複製並貼上到 app.js 中。
jsdocument.addEventListener("DOMContentLoaded", initializeApp); function initializeApp() { const loadFileButton = document.getElementById("loadFileButton"); const outputText = document.getElementById("outputText"); loadFileButton.addEventListener("click", () => fetchAndTransformFile(outputText), ); } async function fetchAndTransformFile(outputElement) { clearOutput(outputElement); try { const response = await fetch("textfile.txt"); const readableStream = response.body; const transformStream = createTransformStream(); const writableStream = createWritableStream(outputElement); await readableStream.pipeThrough(transformStream).pipeTo(writableStream); console.log("File stream processing completed"); } catch (error) { handleError(error, outputElement); } } function createTransformStream() { return new TransformStream({ transform(chunk, controller) { const text = new TextDecoder().decode(chunk); const upperCaseChunk = text.toUpperCase(); controller.enqueue(new TextEncoder().encode(upperCaseChunk)); }, }); } function createWritableStream(outputElement) { return new WritableStream({ write(chunk) { const text = new TextDecoder().decode(chunk); outputElement.textContent += text; }, }); } function clearOutput(outputElement) { outputElement.textContent = ""; outputElement.style.color = "black"; } function handleError(error, outputElement) { console.error("Error during stream processing:", error); outputElement.textContent = `An error occurred: ${error.message}`; outputElement.style.color = "red"; } -
儲存並退出檔案。
-
允許連線到埠 8080。
bashufw allow 8080 -
啟動檔案伺服器。
bashnpx http-server -
訪問應用程式 URL
http://<server-ip>:8080,然後點選 載入並轉換 按鈕。您將看到整個文字檔案被獲取並轉換為大寫字元。
當點選 載入並轉換 按鈕時,fetchAndTransformFile() 函式從伺服器的檔案系統中獲取 textfile.txt。伺服器以 ReadableStream 的形式響應資料,這使得檔案可以分塊處理。在客戶端,這個 ReadableStream 透過一個 TransformStream 進行管道傳輸,該流將每個文字塊轉換為大寫。然後,轉換後的資料塊透過 WritableStream 進行管道傳輸,該流將結果文字附加到 HTML 元素以進行顯示。這表明了 Streams API 如何用於獲取檔案,以及在瀏覽器獲取資料時對其進行處理、轉換和顯示,而不是在記憶體中對整個檔案執行操作。
實際用例和示例
- 在影片流平臺中
- 用例:高效處理和傳輸大型影片檔案。
- 示例:影片流服務可以使用 Streams API 將大型影片檔案分解成更小的塊,進行處理(例如,應用濾鏡或壓縮),然後逐步傳輸給使用者。這可以實現更流暢的播放並減少初始載入時間。
- 在資料視覺化應用程式中
- 用例:即時處理和視覺化大型資料集或連續資料流。
- 示例:金融儀表板可以使用 Streams API 即時處理市場資料。隨著新資料的到來,它可以被轉換、過濾並立即顯示在圖表或圖形上,從而實現即時更新,而不會壓垮瀏覽器的資源。
- 在檔案上傳/下載系統中
- 用例:處理帶有進度跟蹤和即時處理的大檔案傳輸。
- 示例:雲端儲存服務可以使用 Streams API 上傳大檔案。檔案可以作為流讀取,即時壓縮或加密,並分塊傳送到伺服器。這使得能夠進行進度跟蹤、暫停和恢復傳輸,並高效地利用記憶體,特別是對於非常大的檔案。
總結
在本文中,我們深入探討了 Streams API 的概念、用法和實際實現。我們開發了一個基本應用程式,演示瞭如何使用 Streams API 獲取和轉換資料。透過這個實踐示例,我們學習瞭如何讀取、寫入和操作資料流。我們希望這將激發您建立高效、響應迅速的現代 Web 應用程式。
學習此 API 的一些好的後續步驟是執行更復雜的處理。您可以檢視 MDN Streams API 示例之一,它與此專案非常相似,但它手動迴圈資料塊,並在每個新資料塊到達時將其記錄到控制檯。其他的 示例 展示了使用此 API 的不同方法,而 取消 fetch 演示則展示了當客戶端收到所需資料時如何停止進行中的網路操作。
這是一篇由 Vultr 贊助的文章。Vultr 是全球最大的私營雲計算平臺。Vultr 是開發者的首選,已為 185 個國家/地區的 150 萬多客戶提供了靈活、可擴充套件、全球化的雲計算、雲 GPU、裸金屬和雲端儲存解決方案。瞭解更多關於 Vultr 的資訊。