Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fetch: Download progress#425

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 43 additions & 43 deletions5-network/03-fetch-progress/article.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,60 @@

# Fetch:Download progress
# Fetch:progreso de la descarga

The`fetch`method allows to track *download* progress.
El método`fetch`permite rastrear el progreso de *descarga*.

Please note: there's currentlynoway for`fetch`to track *upload* progress. For that purpose, please use[XMLHttpRequest](info:xmlhttprequest),we'll cover it later.
Ten en cuenta: actualmentenohay forma de que`fetch`rastree el progreso de *carga*. Para ese propósito, utiliza[XMLHttpRequest](info:xmlhttprequest),lo cubriremos más adelante.

To track download progress, we can use`response.body` property. It's `ReadableStream` -- a special object that provides body chunk-by-chunk, as it comes. Readable streams are described in the [StreamsAPI](https://streams.spec.whatwg.org/#rs-class) specification.
Para rastrear el progreso de la descarga, podemos usar la propiedad`response.body`. Su `ReadableStream`, un objeto especial que proporciona el cuerpo fragmento a fragmento, tal como viene. Las transmisiones legibles se describen en la especificación de la [API de transmisiones](https://streams.spec.whatwg.org/#rs-class).

Unlike`response.text()`, `response.json()`and other methods, `response.body`gives fullcontrolover the reading process, and we can count how much is consumed at any moment.
A diferencia de`response.text()`, `response.json()`y otros métodos, `response.body`dacontroltotal sobre el proceso de lectura, y podemos contar cuánto se consume en cualquier momento.

Here's the sketch of code that reads the reponse from `response.body`:
Aquí está el bosquejo del código que lee la respuesta de `response.body`:

```js
//instead ofresponse.json()and other methods
//en lugar deresponse.json()y otros métodos
const reader = response.body.getReader();

//infinite loop while the body is downloading
//bucle infinito mientras el cuerpo se descarga
while(true) {
// doneis truefor the last chunk
// valueis Uint8Arrayof the chunkbytes
// donees truepara el último fragmento
// valuees Uint8Arrayde losbytes del fragmento
const {done, value} = await reader.read();

if (done) {
break;
}

console.log(`Received ${value.length} bytes`)
console.log(`Recibí ${value.length} bytes`)
}
```

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`.
El resultado de la llamada`await reader.read()`es un objeto con dos propiedades:
- **`done`** -- `true`cuando la lectura está completa, de lo contrario `false`.
- **`value`** --una matriz de tipo bytes: `Uint8Array`.

```smart
Streams APIalso describes asynchronous iteration over`ReadableStream`with`for await..of` loop, but it's not yet widely supported (see [browser issues](https://github.com/whatwg/streams/issues/778#issuecomment-461341033)),so we use`while` loop.
La APIde transmisiones también describe la iteración asincrónica sobre`ReadableStream`con el bucle`for await..of`, pero aún no es ampliamente compatible (consulta [problemas del navegador](https://github.com/whatwg/streams/issues/778#issuecomment-461341033)),por lo que usamos el bucle`while`.
```

We receive response chunks in the loop, until the loading finishes, that is: until`done`becomes `true`.
Recibimos fragmentos de respuesta en el bucle, hasta que finaliza la carga, es decir: hasta que`done`se convierte en `true`.

To log the progress, we just need for every received fragment`value`to add its length to the counter.
Para registrar el progreso, solo necesitamos que cada`value`de fragmento recibido agregue su longitud al contador.

Here's the full working example that gets the response and logs the progress in console, more explanations to follow:
Aquí está el ejemplo funcional completo que obtiene la respuesta y registra el progreso en la consola, seguido de su explicación:

```js run async
//Step 1:start the fetch and obtain a reader
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits?per_page=100');
//Paso 1:iniciar la búsqueda y obtener un lector
let response = await fetch('https://api.github.com/repos/javascript-tutorial/es.javascript.info/commits?per_page=100');

const reader = response.body.getReader();

//Step 2:get total length
//Paso 2:obtener la longitud total
const contentLength = +response.headers.get('Content-Length');

//Step 3:read the data
let receivedLength = 0; //received that manybytesat the moment
let chunks = []; //array of received binary chunks (comprises the body)
//Paso 3:leer los datos
let receivedLength = 0; //cantidad debytesrecibidos hasta el momento
let chunks = []; //matriz de fragmentos binarios recibidos (comprende el cuerpo)
while(true) {
const {done, value} = await reader.read();

Expand All@@ -65,48 +65,48 @@ while(true) {
chunks.push(value);
receivedLength += value.length;

console.log(`Received ${receivedLength}of ${contentLength}`)
console.log(`Recibí ${receivedLength}de ${contentLength}`)
}

//Step 4:concatenate chunks into single Uint8Array
//Paso 4:concatenar fragmentos en un solo Uint8Array
let chunksAll = new Uint8Array(receivedLength); // (4.1)
let position = 0;
for(let chunk of chunks) {
chunksAll.set(chunk, position); // (4.2)
position += chunk.length;
}

//Step 5:decode into a string
//Paso 5:decodificar en un string
let result = new TextDecoder("utf-8").decode(chunksAll);

//We're done!
//¡Hemos terminado!
let commits = JSON.parse(result);
alert(commits[0].author.login);
```

Let's explain that step-by-step:
Expliquemos eso paso a paso:

1.We perform`fetch`as usual, but instead of calling`response.json()`,we obtain a stream reader `response.body.getReader()`.
1.Realizamos`fetch`como de costumbre, pero en lugar de llamar a`response.json()`,obtenemos un lector de transmisión `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.
2.Prior to reading, we can figure out the full response length from the `Content-Length` header.
Ten en cuenta que no podemos usar ambos métodos para leer la misma respuesta: usa un lector o un método de respuesta para obtener el resultado.
2.Antes de leer, podemos averiguar la longitud completa de la respuesta del encabezado `Content-Length`.

It may be absent for cross-originrequests (see chapter<info:fetch-crossorigin>)and, well, technically a server doesn't have to set it. But usually it's at place.
3.Call`await reader.read()`until it's done.
Puede estar ausente para solicitudes cross-origin(consulta el capítulo<info:fetch-crossorigin>)y, bueno, técnicamente un servidor no tiene que configurarlo. Pero generalmente está en su lugar.
3.Llama a`await reader.read()`hasta que esté listo.

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).
4.At the end, we have`chunks` -- an array of`Uint8Array` byte chunks. We need to join them into a single result. Unfortunately, there'snosingle method that concatenates those, so there's some code to do that:
1.We create`chunksAll = new Uint8Array(receivedLength)` --a same-typed array with the combined length.
2.Then use`.set(chunk, position)`method to copy each`chunk`one after another in it.
5.We have the result in`chunksAll`.It's a byte array though, not a string.
Recopilamos fragmentos de respuesta en la matriz `chunks`.Eso es importante, porque después de consumir la respuesta, no podremos "releerla" usando`response.json()`u otra forma (puedes intentarlo, habrá un error).
4.Al final, tenemos`chunks` - una matriz de fragmentos de bytes`Uint8Array`. Necesitamos unirlos en un solo resultado. Desafortunadamente,nohay un método simple que los concatene, por lo que hay un código para hacerlo:
1.Creamos`chunksAll = new Uint8Array(selectedLength)` --una matriz del mismo tipo con la longitud combinada.
2.Luego usa el método`.set(chunk, position)`para copiar cada`chunk`uno tras otro en él.
5.Tenemos el resultado en`chunksAll`.Sin embargo, es una matriz de bytes, no un string.

To create a string,we need to interpret thesebytes.The built-in[TextDecoder](info:text-decoder)does exactly that. Then we can`JSON.parse` it, if necessary.
Para crear un string,necesitamos interpretar estosbytes.El[TextDecoder](info:text-decoder)nativo hace exactamente eso. Luego podemos usar el resultado en`JSON.parse`, si es necesario.

What if we need binary content instead of astring?That's even simpler. Replace steps 4 and 5with a single line that creates a `Blob`from all chunks:
¿Qué pasa si necesitamos contenido binario en lugar de unstring?Eso es aún más sencillo. Reemplaza los pasos 4 y 5con una sola línea que crea un `Blob`de todos los fragmentos:
```js
let blob = new Blob(chunks);
```

At the end we have the result (as a stringor a blob,whatever is convenient), and progress-tracking in the process.
Al final tenemos el resultado (como un stringo un blob,lo que sea conveniente) y el seguimiento del progreso en el proceso.

Once again, please note, that's not for *upload* progress (noway now with `fetch`),only for *download* progress.
Una vez más, ten en cuenta que eso no es para el progreso de *carga* (hasta ahora esonoes posible con `fetch`),solo para el progreso de *descarga*.
4 changes: 2 additions & 2 deletions5-network/03-fetch-progress/progress.view/index.html
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,13 +12,13 @@
const chunk = await reader.read();

if (chunk.done) {
console.log("done!");
console.log("listo!");
break;
}

chunks.push(chunk.value);
receivedLength += chunk.value.length;
console.log(`${receivedLength}/${contentLength} received`)
console.log(`recibí${receivedLength}/${contentLength}`)
}


Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp