Async / await y el manejo de los bucles en Javascript

Seguro que si has llegado hasta aquí es porque te trae de cabeza los algún problema de las promesas con los bucles. Si estas usando un foreach, un for o cualquier iteración de javascript y tienes de por medias un await… te dará quebraderos de cabezas si no tienes asimilado como funcionan.

🥱Bucles síncronos, los de toda la vida

for (var i=0; i < array.length; i++) {
  var item = array[i];
  // do something with item
}

Y con las nuevas sintasis de ecmascript 6 se puede escribir así:

array.forEach((item) => {
  // do something with item
});

Vale, hasta aquí nada nuevo. Todo ok… programación síncrona, ejecución paso a paso.

Bucles asíncronos

🚨⚠️ Empezamos a complicar la cosa… podríamos escribirlo así…

async function processArray(array) {
  array.forEach(item => {
    // define synchronous anonymous function
    // IT WILL THROW ERROR!
    await func(item);
  })
}

🚨⚠️ Ojo¡ Error¡ Si usamos un await debe ser siempre dentro de una función async

async function processArray(array) {
  array.forEach(async (item) => {
    await func(item);
  })
  console.log('Done!');
}

Pero cuidado… también esta función no se comportaría como nosotros queremos, ya que la impresión del «Done!» debería ser el último paso. El resultado del output sería:

Done!
1
2
3

✅ Ahora sí: bucle síncrono

async function processArray(array) {
  for (const item of array) {
    await delayedLog(item);
  }
  console.log('Done!');
}

Con su resultado como queremos:

1
2
3
Done!

✅ Y ahora, por último lo podemos mejorar para lanzar operaciones síncronas en paralelo:

async function processArray(array) {
  // map array to promises
  const promises = array.map(delayedLog);
  // wait until all promises are resolved
  await Promise.all(promises);
  console.log('Done!');
}

Fuente del artículo: JavaScript loops – how to handle async/await

Deja un comentario