Node.js Web Streams API:與瀏覽器同步的現代串流標準
在 Node.js 的歷史中,我們一直使用 node:stream 模組來處理資料流。雖然它非常強大,但它是 Node.js 特有的,不符合瀏覽器端的 Web 標準。
從 Node.js 18 開始,Node.js 內建支援了與瀏覽器完全一致的 Web Streams API (ReadableStream, WritableStream, TransformStream)。這讓你寫出來的串流處理程式碼能無縫地運行在瀏覽器、Node.js 與 Edge 運算環境(如 Cloudflare Workers)中。
認識 Web Streams API
與 Node.js 原生串流相比,Web Streams 的介面更現代化,並且深度整合了 async/await。
ReadableStream:資料的來源,支援非同步疊代 (Async Iteration)。WritableStream:資料的去處,支援背壓 (Backpressure) 管理。TransformStream:在傳輸過程中對資料進行轉換。
實戰開發:使用 Web Streams 處理 HTTP 請求
Node.js 的 fetch API 底層就是使用 Web Streams。
1. 建立一個簡單的讀取流
const { ReadableStream } = require('node:stream/web');
const readable = new ReadableStream({
start(controller) {
controller.enqueue('Hello ');
controller.enqueue('Web ');
controller.enqueue('Streams!');
controller.close();
},
});
// 使用 for-await 讀取
(async () => {
for await (const chunk of readable) {
console.log('收到:', chunk);
}
})();
2. 在 HTTP Server 中使用 Web Streams
雖然原生的 http 模組使用的是 Node.js 傳統串流,但我們可以輕鬆地進行轉換:
const { Readable } = require('node:stream');
const http = require('http');
http
.createServer(async (req, res) => {
// 將 Node.js 傳統串流轉為 Web ReadableStream
const webStream = Readable.toWeb(req);
const reader = webStream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log('讀取到 Chunk 長度:', value.length);
}
res.end('處理完畢');
})
.listen(3000);
實用的資料轉換:TransformStream
假設我們想要一個能自動將所有英文轉為大寫的串流:
const { TransformStream } = require('node:stream/web');
const upperCaseTransform = new TransformStream({
transform(chunk, controller) {
controller.enqueue(chunk.toString().toUpperCase());
},
});
// 使用 pipeThrough 進行流水線作業
// sourceStream.pipeThrough(upperCaseTransform).pipeTo(destStream);
Node.js 串流與 Web 串流:該選哪一個?
| 特性 | Node.js 原生串流 (Legacy) | Web Streams API (Modern) |
|---|---|---|
| 通用性 | 僅限 Node.js / Electron | 跨平台 (Browser, Node, Deno, Bun) |
| 主要方法 | pipe() | pipeTo(), pipeThrough() |
| 背壓控制 | 基於事件發送與 drain | 內建於 API 底層,更自動化 |
| 發展趨勢 | 依然穩定,主要用於存取 OS 資源 | 未來各種 Fetch/Web API 的標準 |
什麼時候該轉向 Web Streams?
- 推薦:開發開源套件(需跨環境支援)、使用 Fetch API 處理大型檔案下載、或是追求更現代的非同步程式設計風格時。
- 沿用傳統:處理磁碟檔案 (
fs.createReadStream)、或是目前現存於 Node.js 核心大部分的 API 呼叫。
總結
- Web Streams 是未來的跨平台標準。
- 內建
pipeThrough機制讓資料處理像樂高積木一樣好組裝。 - 掌握 Web Streams 能讓你的 Node.js 技術棧更具備「雲端原生」與「跨端開發」的優勢。