for await...of

La sentencia for await...of crea un bucle iterando tanto sobre objetos iterables asincrónicos como sincrónicos, incluyendo: built-in String, Array, objetos Array-like (por ej., argumentsNodeList), TypedArray, Map, 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.

Sintaxis

for await (variable of iterable) {
  sentencia
}
variable
En cada iteración, el valor de una propiedad diferente es asignado a variable. variable puede ser declarada con const, let, o var.
iterable
Objeto sobre cuyas propiedades se itera.

Iterando sobre iterables asincrónicos

También puedes iterar sobre un objeto que explícitamente implementa el protocolo async iterable:

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

Iterando sobre funciones generadoras asincrónicas

Debido a que las funciones generadoras asincrónicas implementan el protocolo async iterator, las mismas pueden ser iteradas utilizando for await... of

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

Para un ejemplo más concreto de iteración sobre una función generadora utilizando for await... of, 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.

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');

Especificaciones

Especificación Estado Comentarios
ECMAScript Latest Draft (ECMA-262)
La definición de 'ECMAScript Language: The for-in, for-of, and for-await-of Statements' en esta especificación.
Draft

Compatibilidad de Navegadores

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome para AndroidFirefox para AndroidOpera para AndroidSafari en iOSSamsung InternetNode.js
for await...of
Experimental
Chrome Soporte completo 63Edge Sin soporte NoFirefox Soporte completo 57IE Sin soporte NoOpera Soporte completo 50Safari Soporte completo 11WebView Android Soporte completo 63Chrome Android Soporte completo 63Firefox Android Soporte completo 57Opera Android Soporte completo 46Safari iOS ? Samsung Internet Android Soporte completo 8.0nodejs Soporte completo 10.0.0
Soporte completo 10.0.0
Sin soporte 8.10.0 — 10.0.0
Deshabilitado
Deshabilitado From version 8.10.0 until version 10.0.0 (exclusive): this feature is behind the --harmony-async-iteration runtime flag.

Leyenda

Soporte completo  
Soporte completo
Sin soporte  
Sin soporte
Compatibilidad desconocida  
Compatibilidad desconocida
Experimental. Esperar que el comportamiento cambie en el futuro.
Experimental. Esperar que el comportamiento cambie en el futuro.
El usuario debe de habilitar explícitamente esta característica.
El usuario debe de habilitar explícitamente esta característica.

Ver también