Fetch download progress
5864 ワード
To track download progress, we can use
Unlike
Here’s the sketch of code that reads the response from
The result of
We perform
Please note, we can’t use both these methods to read the same response: either use a reader or a response method to get the result.
Prior to reading, we can figure out the full response length from the
It may be absent for cross-origin requests (see chapter Fetch: Cross-Origin Requests ) and, well, technically a server doesn’t have to set it. But usually it’s at place.
Call
We gather response chunks in the array
At the end, we have We create Then use
We have the result in
To create a string, we need to interpret these bytes. The built-in TextDecoder does exactly that. Then we can
What if we need binary content instead of a string? That’s even simpler. Replace steps 4 and 5 with a single line that creates a
response.body
property. It’s a ReadableStream
– a special object that provides body chunk-by-chunk, as it comes. Readable streams are described in the Streams API specification.Unlike
response.text()
, response.json()
and other methods, response.body
gives full control over the reading process, and we can count how much is consumed at any moment.Here’s the sketch of code that reads the response from
response.body
:The result of
await reader.read()
call is an object with two properties:done
– true
when the reading is complete, otherwise false
. value
– a typed array of bytes: Uint8Array
. // instead of response.json() and other methods
const reader = response.body.getReader();
// infinite loop while the body is downloading
while(true) {
// done is true for the last chunk
// value is Uint8Array of the chunk bytes
const {done, value} = await reader.read();
if (done) {
break;
}
console.log(`Received ${value.length} bytes`)
}
Let’s explain that step-by-step:We perform
fetch
as usual, but instead of calling response.json()
, we obtain a stream reader response.body.getReader()
.Please note, we can’t use both these methods to read the same response: either use a reader or a response method to get the result.
Prior to reading, we can figure out the full response length from the
Content-Length
header.It may be absent for cross-origin requests (see chapter Fetch: Cross-Origin Requests ) and, well, technically a server doesn’t have to set it. But usually it’s at place.
Call
await reader.read()
until it’s done.We gather response chunks in the array
chunks
. That’s important, because after the response is consumed, we won’t be able to “re-read” it using response.json()
or another way (you can try, there’ll be an error).At the end, we have
chunks
– an array of Uint8Array
byte chunks. We need to join them into a single result. Unfortunately, there’s no single method that concatenates those, so there’s some code to do that:chunksAll = new Uint8Array(receivedLength)
– a same-typed array with the combined length. .set(chunk, position)
method to copy each chunk
one after another in it. We have the result in
chunksAll
. It’s a byte array though, not a string.To create a string, we need to interpret these bytes. The built-in TextDecoder does exactly that. Then we can
JSON.parse
it, if necessary.What if we need binary content instead of a string? That’s even simpler. Replace steps 4 and 5 with a single line that creates a
Blob
from all chunks:let blob = new Blob(chunks);
Reference
この問題について(Fetch download progress), 我々は、より多くの情報をここで見つけました https://velog.io/@hqillz/Fetch-download-progressテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol