Cómo usar async / await con un Array map
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 { },Promise { }]
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)
})