簡體   English   中英

Web Streams 和 Node.js Stream API 之間的區別

[英]Difference between Web Streams and Node.js Stream APIs

我正在構建一個文件上傳應用程序來熟悉流的概念。 我正在嘗試將文件列表或 blob 轉換為流,然后將其上傳到后端並將其存儲在文件系統中。

我分別對前端和后端實現沒有問題,但我很難將兩者聯系起來。 我的主要問題是我不明白Web Streams APINode.js Streams API之間的區別。 我設法將瀏覽器中選定輸入文件的 blob 轉換為 Web ReadableStream ,但我嘗試的包(請求的axios ,WebSocket 的socket.iosocket.io-stream )只接受 Node.js 版本的 Stream 作為參數。 我也無法將 Web ReadableStream 通過管道傳輸到 Node.js Writeable 或 Duplex Stream。 方法名稱也不同(例如:Web API 中的pipeTopipeThrough和 Node.js API 中的pipe )。

我知道 Node.js 和瀏覽器之間存在實現差異,但我天真地認為 API 應該是相似的。 我能否以某種方式在 Web 流和瀏覽器化的 Node.js 流之間進行簡單的轉換,而我遺漏了什么? stream-browserify上使用 Web Stream API 是否值得?

根據文檔,自版本 16 起,Node.js 包含WebStreams API 的(仍處於試驗階段)實現

舊的 Stream API 現在(自 v.17 起)獲得了一些toWeb/FromWeb方法來橋接兩者。

這里有一些信息。

It's not too difficult to convert a web stream to a Node.js stream manually, but you should really try to find a library that accepts native web streams instead of shoehorning a Node.js shim for the stream built-in into the browser with Browserify.

但是,如果證明有必要在瀏覽器中使用 Node.js stream 墊片,則需要安裝stream-browserify並像這樣使用:

import { Readable, Writable } from 'stream-browserify;'

// window.ReadableStream to Node.js Readable
const webRSToNodeRS = rs => {
  const reader = rs.getReader();
  const out = new Readable();
  reader.read().then(async ({ value, done }) => {
    while (!done) {
      out.push(value);
      ({ done, value }) = await reader.read();
    }
    out.push(null);
  });
  return out;
}

// window.WritableStream to Node.js Writable
const webWSToNodeWS = ws => {
  const writer = ws.getWriter();
  const out = new Writable();
  out._write = (chunk, encoding, callback) => {
    writer.write(chunk);
    callback();
  };
  out._final = callback => {
    writer.close();
    callback();
  };
  return out;
}

這些方法應該足以在 web 和節點流之間進行完全互操作。 例如,如果您想將 pipe 和 web ReadableStream 轉換為 Node.js Writable/Duplex:

const pipeWebRSToWritable = (rs, writable) => {
  // After converting you can use the normal pipe methods
  webRSToNodeRS(rs).pipe(writable);
}

但是我想提一下,您不需要從客戶端到服務器的 stream 數據的庫。 fetch API 原生支持 web 流,並且可能是您應該使用 go 的方式。

// POST a ReadableStream (perhaps of a file) to the server
// Way easier and more performant than using a 3rd party library...
const postRSToServer = rs => fetch('/your/server/endpoint', {
  method: 'POST',
  body: rs
});

最后一點:確保您直接使用Blob.prototype.stream方法(在File object 上調用此方法,例如file.stream() ,因為File擴展了Blob )。 有一些方法可以從 JS 中的文件中獲取ReadableStream ,實際上最終會將所有文件加載到瀏覽器中的 memory 中,這是您不想要的。

對於那些就node-fetch返回的流提出這個問題的人(比如我自己),請注意undicifetchweb 兼容實現, 最終可能成為官方節點實現

另外,請參閱leonbloy 的回答RE 新的 toWeb/fromWeb 方法和 WebStreams API。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM