ReadableStream
Baseline 廣泛可用 *
注意:此功能在 Web Workers 中可用。
ReadableStream 介面是 Streams API 的一部分,代表一個可讀的位元組資料流。 Fetch API 透過 body 屬性提供了一個 ReadableStream 的具體例項,該屬性是 Response 物件的一部分。
ReadableStream 是一個 可轉移物件。
建構函式
ReadableStream()-
從給定的處理程式建立並返回一個可讀流物件。
例項屬性
ReadableStream.locked只讀-
返回一個布林值,指示可讀流是否已被讀取器鎖定。
靜態方法
ReadableStream.from()實驗性-
從提供的可迭代物件或非同步可迭代物件(如陣列、集合、非同步生成器等)返回
ReadableStream。
例項方法
ReadableStream.cancel()-
返回一個
Promise,當流被取消時解析。呼叫此方法表示消費者對該流不再感興趣。提供的reason引數將傳遞給底層源,源可能會也可能不會使用它。 ReadableStream.getReader()-
建立一個讀取器並將流鎖定到該讀取器。當流被鎖定後,在釋放此讀取器之前,不能獲取其他讀取器。
ReadableStream.pipeThrough()-
提供了一種鏈式方式,將當前流透過轉換流或任何其他可寫/可讀對進行管道傳輸。
ReadableStream.pipeTo()-
將當前 ReadableStream 管道傳輸到指定的
WritableStream,並返回一個Promise。當管道傳輸成功完成時,該 Promise 會 fulfilled;如果遇到任何錯誤,則會 rejected。 ReadableStream.tee()-
tee方法 將此可讀流進行分叉,返回一個包含兩個新ReadableStream例項的兩個元素的陣列。這兩個流接收相同的資料。
非同步迭代
ReadableStream 實現 非同步迭代協議。這使得可以使用 for await...of 語法非同步迭代流中的塊。
const stream = new ReadableStream(getSomeSource());
for await (const chunk of stream) {
// Do something with each 'chunk'
}
非同步迭代器會消耗流,直到它沒有更多資料或終止。迴圈也可以由於 break、throw 或 return 語句而提前退出。
在迭代期間,流會被鎖定,以防止其他消費者獲取讀取器(嘗試迭代一個已被鎖定的流將丟擲 TypeError)。此鎖在迴圈退出時會被釋放。
預設情況下,退出迴圈也會取消流,使其無法再被使用。要在退出迴圈後繼續使用流,請將 { preventCancel: true } 傳遞給流的 values() 方法。
for await (const chunk of stream.values({ preventCancel: true })) {
// Do something with 'chunk'
break;
}
// Acquire a reader for the stream and continue reading ...
示例
Fetch 流
在以下示例中,建立了一個人工 Response 物件,以將從其他資源獲取的 HTML 片段流式傳輸到瀏覽器。
它演示了 ReadableStream 與 Uint8Array 結合使用的用法。
fetch("https://www.example.org")
.then((response) => response.body)
.then((rb) => {
const reader = rb.getReader();
return new ReadableStream({
start(controller) {
// The following function handles each data chunk
function push() {
// "done" is a Boolean and value a "Uint8Array"
reader.read().then(({ done, value }) => {
// If there is no more data to read
if (done) {
console.log("done", done);
controller.close();
return;
}
// Get the data and send it to the browser via the controller
controller.enqueue(value);
// Check chunks by logging to the console
console.log(done, value);
push();
});
}
push();
},
});
})
.then((stream) =>
// Respond with our stream
new Response(stream, { headers: { "Content-Type": "text/html" } }).text(),
)
.then((result) => {
// Do things with result
console.log(result);
});
將迭代器或非同步迭代器轉換為流
from() 靜態方法可以將迭代器(如 Array 或 Map)或 (非同步)迭代器 轉換為可讀流。
const myReadableStream = ReadableStream.from(iteratorOrAsyncIterator);
在不支援 from() 方法的瀏覽器中,您可以改為建立自己的 自定義可讀流 來達到相同的效果。
function iteratorToStream(iterator) {
return new ReadableStream({
async pull(controller) {
const { value, done } = await iterator.next();
if (value) {
controller.enqueue(value);
}
if (done) {
controller.close();
}
},
});
}
警告:此示例假定返回值(在 done 為 true 時為 value)如果存在,也應視為要入隊的塊。某些迭代器 API 可能將返回值用於不同目的。您可能需要根據您互動的 API 來調整程式碼。
使用 for await...of 對流進行非同步迭代
此示例演示瞭如何使用 for await...of 迴圈處理 fetch() 響應,以迭代到達的塊。
const response = await fetch("https://www.example.org");
let total = 0;
// Iterate response.body (a ReadableStream) asynchronously
for await (const chunk of response.body) {
// Do something with each chunk
// Here we just accumulate the size of the response.
total += chunk.length;
}
// Do something with the total
console.log(total);
規範
| 規範 |
|---|
| Streams # rs-class |
瀏覽器相容性
載入中…