1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
---
title: for await...of
slug: Web/JavaScript/Referencia/Sentencias/for-await...of
tags:
- Iteración
- JavaScript
- Referencia
- Sentencia
- asincrónico
- await
- iterar
translation_of: Web/JavaScript/Reference/Statements/for-await...of
---
<div>{{jsSidebar("Statements")}}</div>
<p>La <strong>sentencia</strong> <strong><code>for await...of</code> </strong>crea un bucle iterando tanto sobre objetos iterables asincrónicos como sincrónicos, incluyendo: built-in {{jsxref("String")}}, {{jsxref("Array")}}, objetos <code>Array</code>-like (por ej., {{jsxref("Functions/arguments", "arguments")}} o {{domxref("NodeList")}}), {{jsxref("TypedArray")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, y async/sync iterables definidos por el usuario. Invoca un hook de iteración personalizada con sentencias a ser ejecutadas por el valor de cada propiedad diferente del objeto.</p>
<p class="hidden">El código fuente de este ejemplo interactivo está almacenado en un repositorio Github. Si te gustaría contribuir al proyecto de ejemplos interactivos, por favor clona <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> y envíanos un pull request.</p>
<h2 id="Sintaxis">Sintaxis</h2>
<pre class="syntaxbox">for await (<em>variable</em> of <em>iterable</em>) {
<em>sentencia
</em>}
</pre>
<dl>
<dt><code>variable</code></dt>
<dd>En cada iteración, el valor de una propiedad diferente es asignado a <em>variable</em>. <em>variable</em> puede ser declarada con <code>const</code>, <code>let</code>, o <code>var</code>.</dd>
<dt><code>iterable</code></dt>
<dd>Objeto sobre cuyas propiedades se itera.</dd>
</dl>
<h3 id="Iterando_sobre_iterables_asincrónicos">Iterando sobre iterables asincrónicos</h3>
<p>También puedes iterar sobre un objeto que explícitamente implementa el protocolo async iterable:</p>
<pre class="brush:js">var asyncIterable = {
[Symbol.asyncIterator]() {
return {
i: 0,
next() {
if (this.i < 3) {
return Promise.resolve({ value: this.i++, done: false });
}
return Promise.resolve({ done: true });
}
};
}
};
(async function() {
for await (let num of asyncIterable) {
console.log(num);
}
})();
// 0
// 1
// 2
</pre>
<h3 id="Iterando_sobre_funciones_generadoras_asincrónicas">Iterando sobre funciones generadoras asincrónicas</h3>
<p>Debido a que las funciones generadoras asincrónicas implementan el protocolo async iterator, las mismas pueden ser iteradas utilizando <code>for await... of</code></p>
<pre class="brush: js">async function* asyncGenerator() {
var i = 0;
while (i < 3) {
yield i++;
}
}
(async function() {
for await (let num of asyncGenerator()) {
console.log(num);
}
})();
// 0
// 1
// 2</pre>
<p>Para un ejemplo más concreto de iteración sobre una función generadora utilizando <code>for await... of</code>, considera iterar sobre datos provistos por una API. Este ejemplo primero crea un iterador asincrónico para un stream de datos, luego lo utiliza para obtener el tamaño de la respuesta desde la API.</p>
<pre class="brush: js">async function* streamAsyncIterator(stream) {
const reader = stream.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
return;
}
yield value;
}
} finally {
reader.releaseLock();
}
}
// Obtiene datos desde url y calcula el tamaño de la respuesta utilizando la función generadora asincrónica.
async function getResponseSize(url) {
const response = await fetch(url);
// Almacenará el tamaño de la respuesta en bytes.
let responseSize = 0;
// El buble for-await-of. Itera asincrónicamente sobre cada parte de la respuesta.
for await (const chunk of streamAsyncIterator(response.body)) {
// Incrementando el tamaño total.
responseSize += chunk.length;
}
console.log(`Tamaño de la respuesta: ${responseSize} bytes`);
// salida esperada: "Tamaño de la respuesta: 1071472"
return responseSize;
}
getResponseSize('https://jsonplaceholder.typicode.com/photos');</pre>
<h2 id="Especificaciones">Especificaciones</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Especificación</th>
<th scope="col">Estado</th>
<th scope="col">Comentarios</th>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'ECMAScript Language: The for-in, for-of, and for-await-of Statements')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="Compatibilidad_de_Navegadores">Compatibilidad de Navegadores</h2>
<div class="hidden">La tabla de compatiblidad de esta página es generada a partir de datos estructurados. Si te gustaría contribuir a estos datos, por favor clona <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> y envíanos un pull request.</div>
<p>{{Compat("javascript.statements.for_await_of")}}</p>
<h2 id="Ver_también">Ver también</h2>
<ul>
<li>{{jsxref("Statements/for...of")}}</li>
</ul>
|