You signed in with another tab or window.Reload to refresh your session.You signed out in another tab or window.Reload to refresh your session.You switched accounts on another tab or window.Reload to refresh your session.Dismiss alert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
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');
//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*.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.