Dado o seguinte 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 produz o seguinte erro:
TS2322: O tipo 'Promessa <número> []' não pode ser atribuído ao tipo 'número []'. O tipo 'Promessa <número> não pode ser atribuído ao tipo' número '.
Como posso corrigir isso? Como posso fazer async await
e Array.map
trabalhar juntos?
arr.map()
é síncrono e não retorna uma promessa.map
, que espera uma síncrona, e espera que funcione.async
, está fazendo com que essa função retorne uma promessa. Então, é claro, um mapa de assíncrono retorna uma matriz de promessas :)Respostas:
O problema aqui é que você está tentando
await
uma série de promessas, e não uma promessa. Isso não faz o que você espera.Quando o objeto passado
await
não é uma promessa,await
simplesmente retorna o valor como está imediatamente, em vez de tentar resolvê-lo. Portanto, desde que você passouawait
uma matriz (de objetos Promise) aqui em vez de uma Promessa, o valor retornado por wait é simplesmente essa matriz, que é do tipoPromise<number>[]
.O que você precisa fazer aqui é chamar
Promise.all
a matriz retornada pormap
para convertê-la em uma única promessa antes deawait
recebê-la.De acordo com os documentos MDN para
Promise.all
:Então, no seu caso:
Isso resolverá o erro específico que você está encontrando aqui.
fonte
:
significam os dois pontos?callAsynchronousOperation(item);
com e semawait
dentro da função de mapa assíncrono?await
a função aguardará a conclusão da operação assíncrona (ou falhará) antes de continuar; caso contrário, ela continuará imediatamente sem aguardar.Existe outra solução para isso, se você não estiver usando promessas nativas, mas o Bluebird.
Você também pode tentar usar Promise.map () , misturando array.map e Promise.all
No seu caso:
fonte
Promise.mapSeries
ouPromise.each
são sequenciais,Promise.map
inicia todos de uma vez.concurrency
opçãoSe você mapear para uma matriz de promessas, poderá resolvê-las todas para uma matriz de números. Consulte Promise.all .
fonte
Eu recomendo usar Promise.all, como mencionado acima, mas se você realmente quiser evitar essa abordagem, poderá fazer um loop for ou qualquer outro:
fonte
Solução abaixo para processar todos os elementos de uma matriz de forma assíncrona E preservar a ordem:
Também codepen .
Observe que apenas "aguardamos" o Promise.all. Chamamos calc sem "aguardar" várias vezes e coletamos uma série de promessas não resolvidas imediatamente. Então Promise.all aguarda a resolução de todos eles e retorna uma matriz com os valores resolvidos em ordem.
fonte