Cómo usar async / await con un Array map

Fácil - 2 min. lectura

Cuando aplicamos un map a un array de datos, ejecutamos un callback para modificar los datos de cada iteración.
Pero qué ocurre si en este callback queremos hacer alguna llamada asíncrona, ¿es posible usar async/await en este callback?

Veamos un ejemplo:

const esperarUnSegundo = () => new Promise(resolve => setTimeout(resolve, 1000));
const numeros = [1,2]
const dobles = numeros.map( async (numero) => {
  await esperarUnSegundo()
  return numero * 2
})
console.log(dobles) //[Promise { <pending> },Promise { <pending> }]

Si te fijas, lo que obtenemos es un array de promesas pendientes y esto nos da una pista sobre cómo podemos solucionarlo.
Como tenemos ese array de promesas, lo que tendremos que hacer es esperar que todas estas promesas queden resueltas y para ello usaremos Promise.all()

(async () => {
    const numeros = [1,2]
    const esperarUnSegundo = () => new Promise(resolve => setTimeout(resolve, 1000));
    const dobles = await Promise.all(numeros.map( async (numero) => {
        await esperarUnSegundo()
        return numero * 2
    }))
    console.log(dobles)
})();

Otras formas

for .. of

Con for .. of es posible realizar llamadas asíncronas dentro del mismo bucle.
Atendiendo al ejemplo anterior podríamos hacerlo de la siguiente forma:

(async () => {
  const numeros = [1,2]
  const esperarUnSegundo = () => new Promise(resolve => setTimeout(resolve, 1000));
  const dobles = []
  for (const numero of numeros){
    await esperarUnSegundo()
    dobles.push(numero * 2)
  }
  console.log(dobles)
})()

moderm-async

Modern-async es una librería externa que podemos usar para realizar operaciones con async/await y promesas.

Para usarla debemos instalarlo mediante NPM o Yarn:

npm install --save modern-async
yarn add modern-async
import { map, asyncRoot, sleep } from 'modern-async'

asyncRoot(async () => {
  const array = [1, 2]
  const result = await map(array, async (v) => {
    await sleep(1)
    return v * 2
  })
  console.log(result)
})