ReadableStreamBYOBReader: read() 方法
注意:此功能在 Web Workers 中可用。
read() 方法是 ReadableStreamBYOBReader 介面的一個方法,用於從關聯的 可讀位元組流 中讀取資料到一個使用者提供的緩衝區檢視。如果流的內部佇列中有資料,則資料請求將從佇列中滿足。如果佇列為空,則請求可能會直接從底層位元組源進行零複製傳輸。
該方法接受一個檢視作為引數,該檢視指定了要將資料讀取到哪個緩衝區中,並返回一個 Promise。當資料可用或流被取消時,該 Promise 會以一個包含 value 和 done 屬性的物件進行 fulfilled。如果流發生錯誤,Promise 會以相關的錯誤物件進行 rejected。
當提供一個數據塊時,value 屬性將包含一個新的檢視。這個檢視將與傳遞給 read() 方法的原始 view 具有相同的緩衝區/底層記憶體,並且型別也相同,只是現在填充了新的資料塊。請注意,一旦 Promise fulfilled,傳遞給方法的原始 view 將被分離,不再可用。如果流被取消,Promise 將以 value: undefined fulfilled。在這種情況下,view 的底層記憶體區域將被丟棄,不會返回給呼叫者(檢視緩衝區中所有先前讀取的資料都將丟失)。
done 屬性指示是否還期望有更多資料。如果流已關閉或被取消,則值為 true,否則為 false。
該方法還有一個可選的 options.min 引數,可用於指定在流處於活動狀態時,必須有多少個元素可用後 Promise 才會 fulfilled。在 value 屬性中返回的檢視將始終至少包含此數量的元素,除非流已關閉。
語法
read(view)
read(view, options)
引數
view-
要將資料讀取到的檢視。
options可選-
選項如下:
min-
在流處於活動狀態時,在 Promise fulfilled 之前必須讀取的最少元素數量。如果未提供,Promise 將在至少讀取一個元素(最多檢視的最大尺寸)後 resolve。此數字不得大於正在讀取的檢視。
返回值
一個 Promise,它會根據流的狀態 fulfilled/rejected。結果物件包含兩個屬性:value 和 done。
以下是可能的情況:
-
如果有一個數據塊可用且流仍處於活動狀態,則結果的
done為false,value是一個包含新資料的檢視。這是與傳遞給read()方法的view型別相同且在同一底層記憶體上的檢視。原始view將被分離,不再可用。 -
如果流已關閉,則結果的
done為true,value具有與上述相同的屬性。 -
如果流被取消,則結果的
done為true,value為undefined。在這種情況下,底層記憶體將被丟棄。 -
如果流丟擲錯誤,Promise 將以相關的錯誤 rejection。
異常
TypeError-
源物件不是
ReadableStreamBYOBReader,流沒有所有者,檢視不是物件或已失效,檢視的長度為 0,options.min為 0,或者呼叫了ReadableStreamBYOBReader.releaseLock()(當存在待處理的讀取請求時)。 RangeError-
options.min值大於正在寫入的檢視。
示例
讀取到檢視中
這裡的示例程式碼摘自 使用可讀位元組流 中的即時示例。
首先,我們透過在流上呼叫 ReadableStream.getReader() 來建立 reader,並在選項引數中指定 mode: "byob"。我們還需要建立一個 ArrayBuffer,它是我們將要寫入的檢視的“底層記憶體”。
const reader = stream.getReader({ mode: "byob" });
let buffer = new ArrayBuffer(4000);
下面是一個使用 reader 的函式。該函式遞迴呼叫 read() 方法將資料讀入緩衝區。該方法接受一個 Uint8Array 型別陣列,它是原始陣列緩衝區中尚未寫入部分的一個檢視。檢視的引數是根據之前呼叫接收到的資料計算的,這些資料定義了原始陣列緩衝區的偏移量。
readStream(reader);
function readStream(reader) {
let bytesReceived = 0;
let offset = 0;
while (offset < buffer.byteLength) {
// read() returns a promise that fulfills when a value has been received
reader
.read(new Uint8Array(buffer, offset, buffer.byteLength - offset))
.then(function processBytes({ done, value }) {
// Result objects contain two properties:
// done - true if the stream has already given all its data.
// value - some data. 'undefined' if the reader is canceled.
if (done) {
// There is no more data in the stream
return;
}
buffer = value.buffer;
offset += value.byteLength;
bytesReceived += value.byteLength;
// Read some more, and call this function again
// Note that here we create a new view over the original buffer.
return reader
.read(new Uint8Array(buffer, offset, buffer.byteLength - offset))
.then(processBytes);
});
}
}
當流中沒有更多資料時,read() 方法將以 done 屬性設定為 true 的物件 fulfilled,然後函式返回。
讀取最少數量的元素
此示例與上一個示例幾乎完全相同,只是我們修改了程式碼,使每次迭代讀取最少 101 個元素。
我們還將其製作成了一個即時示例。請注意,大部分程式碼與示例無關,因此被隱藏了。有關更多資訊,請參閱 使用可讀位元組流。
JavaScript
function readStream(reader) {
let bytesReceived = 0;
let offset = 0;
while (offset < buffer.byteLength) {
// read() returns a promise that resolves when a value has been received
reader
.read(new Uint8Array(buffer, offset, buffer.byteLength - offset), {
min: 101,
})
.then(async function processText({ done, value }) {
// Result objects contain two properties:
// done - true if the stream has already given all its data.
// value - some data. Always undefined when done is true.
if (done) {
logConsumer(
`readStream() complete. Read ${value.byteLength} bytes (total: ${bytesReceived})`,
);
return;
}
buffer = value.buffer;
offset += value.byteLength;
bytesReceived += value.byteLength;
// logConsumer(`Read ${bytesReceived} bytes: ${value}`);
logConsumer(`Read ${value.byteLength} bytes (total: ${bytesReceived})`);
result += value;
// Read some more, and call this function again
return reader
.read(new Uint8Array(buffer, offset, buffer.byteLength - offset), {
min: 101,
})
.then(processText);
});
}
}
結果
下面顯示了底層推送源(左)和消費者(右)的日誌記錄。請注意,如果瀏覽器支援 options.min 引數,那麼每次將返回至少 101 個元素(通常更多),除非流關閉。
規範
| 規範 |
|---|
| Streams # byob-reader-read |
瀏覽器相容性
載入中…