Dado el siguiente código:
var arr = [1,2,3,4,5];
var results: number[] = await arr.map(async (item): Promise<number> => {
await callAsynchronousOperation(item);
return item + 1;
});
que produce el siguiente error:
TS2322: El tipo 'Promesa <número> []' no se puede asignar al tipo 'número []'. El tipo 'Promesa <número> no se puede asignar al tipo' número '.
¿Cómo puedo arreglarlo? ¿Cómo puedo hacer async await
y Array.map
trabajar juntos?
arr.map()
es sincrónico y no devuelve una promesa.map
, que espera una sincrónica, y espera que funcione.async
, está haciendo que esa función devuelva una promesa. Entonces, por supuesto, un mapa asíncrono devuelve una serie de promesas :)Respuestas:
El problema aquí es que está tratando de hacer
await
una serie de promesas en lugar de una promesa. Esto no hace lo que esperas.Cuando el objeto pasado
await
no es una Promesa,await
simplemente devuelve el valor tal como está inmediatamente en lugar de intentar resolverlo. Entonces, dado que pasóawait
una matriz (de objetos Promise) aquí en lugar de una Promesa, el valor devuelto por wait es simplemente esa matriz, que es de tipoPromise<number>[]
.Lo que debe hacer aquí es llamar
Promise.all
a la matriz devueltamap
para convertirla en una sola Promesa antes deawait
iniciarla.De acuerdo con los documentos de MDN para
Promise.all
:Entonces en tu caso:
Esto resolverá el error específico que encuentre aquí.
fuente
:
significan los dos puntos?callAsynchronousOperation(item);
con y sinawait
dentro de la función de mapa asíncrono?await
la función esperará a que la operación asincrónica se complete (o falle) antes de continuar, de lo contrario, continuará inmediatamente sin esperar.Hay otra solución si no está utilizando Promises nativas sino Bluebird.
También puede intentar usar Promise.map () , mezclando el array.map y Promise.all
En tu caso:
fuente
Promise.mapSeries
oPromise.each
son secuenciales, losPromise.map
inicia todos a la vez.concurrency
opción.Si asigna una matriz de Promesas, puede resolverlas todas en una matriz de números. Ver Promesa.todos .
fuente
Recomiendo usar Promise.all como se mencionó anteriormente, pero si realmente desea evitar ese enfoque, puede hacer un bucle a favor o en cualquier otro:
fuente
Solución a continuación para procesar todos los elementos de una matriz de forma asíncrona Y preservar el orden:
También codepen .
Note que solo "esperamos" por Promise.all. Llamamos calc sin "esperar" varias veces, y recopilamos una serie de promesas no resueltas de inmediato. Luego, Promise.all espera la resolución de todos ellos y devuelve una matriz con los valores resueltos en orden.
fuente