Saltar al contenido

Usando async/await con un bucle forEach

Te damos el resultado a este enigma, o por lo menos eso esperamos. Si sigues con interrogantes puedes dejarlo en el apartado de comentarios y sin dudarlo te responderemos

Solución:

Seguro que el código funciona, pero estoy bastante seguro de que no hace lo que esperas que haga. Simplemente dispara múltiples llamadas asincrónicas, pero el printFiles la función regresa inmediatamente después de eso.

Lectura en secuencia

Si desea leer los archivos en secuencia, no se puede usar forEach Por supuesto. Solo usa un moderno for … of bucle en su lugar, en el que await funcionará como se esperaba:

async function printFiles () 
  const files = await getFilePaths();

  for (const file of files) 
    const contents = await fs.readFile(file, 'utf8');
    console.log(contents);
  

Lectura en paralelo

Si desea leer los archivos en paralelo, no se puede usar forEach Por supuesto. Cada una de las async Las llamadas a la función de devolución de llamada devuelven una promesa, pero las está descartando en lugar de esperarlas. Solo usa map en su lugar, y puede esperar el array de promesas que vas a conseguir con Promise.all:

async function printFiles () 
  const files = await getFilePaths();

  await Promise.all(files.map(async (file) => 
    const contents = await fs.readFile(file, 'utf8')
    console.log(contents)
  ));

Con ES2018, puede simplificar en gran medida todas las respuestas anteriores a:

async function printFiles () 
  const files = await getFilePaths()

  for await (const contents of files.map(file => fs.readFile(file, 'utf8'))) 
    console.log(contents)
  

Ver especificación: propuesta-asincrónica-iteración


2018-09-10: Esta respuesta ha recibido mucha atención recientemente, consulte la publicación del blog de Axel Rauschmayer para obtener más información sobre la iteración asíncrona: ES2018: iteración asíncrona

En vez de Promise.all junto con Array.prototype.map (lo que no garantiza el orden en que se Promises están resueltos), yo uso Array.prototype.reducecomenzando con un resuelto Promise:

async function printFiles () 
  const files = await getFilePaths();

  await files.reduce(async (promise, file) => 
    // This line will wait for the last async function to finish.
    // The first iteration uses an already resolved Promise
    // so, it will immediately continue.
    await promise;
    const contents = await fs.readFile(file, 'utf8');
    console.log(contents);
  , Promise.resolve());

Si te sientes impulsado, tienes la opción de dejar una noticia acerca de qué le añadirías a este artículo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *