Compte tenu du code suivant:
var arr = [1,2,3,4,5];
var results: number[] = await arr.map(async (item): Promise<number> => {
await callAsynchronousOperation(item);
return item + 1;
});
ce qui produit l'erreur suivante:
TS2322: Le type «Promise <numéro> []» ne peut pas être affecté au type «numéro []». Le type «Promise <numéro> ne peut pas être affecté au type« numéro ».
Comment puis-je y remédier? Comment puis-je créer async await
et Array.map
travailler ensemble?
arr.map()
est synchrone et ne renvoie pas de promesse.map
, qui attend une opération synchrone et s'attendre à ce qu'elle fonctionne.async
, vous faites en sorte que cette fonction renvoie une promesse. Alors bien sûr, une carte d'async renvoie un tableau de promesses :)Réponses:
Le problème ici est que vous essayez
await
un éventail de promesses plutôt qu'une promesse. Cela ne fait pas ce que vous attendez.Lorsque l'objet passé à
await
n'est pas une promesse,await
renvoie simplement la valeur telle quelle immédiatement au lieu d'essayer de la résoudre. Donc, puisque vous avez passéawait
un tableau (d'objets Promise) ici au lieu d'une Promise, la valeur retournée par await est simplement ce tableau, qui est de typePromise<number>[]
.Ce que vous devez faire ici est d'appeler
Promise.all
le tableau renvoyé parmap
afin de le convertir en une seule promesse avant de l'await
engager.Selon la documentation MDN pour
Promise.all
:Donc dans votre cas:
Cela résoudra l'erreur spécifique que vous rencontrez ici.
la source
:
signifient les deux points?callAsynchronousOperation(item);
avec et sansawait
à l'intérieur de la fonction de carte asynchrone?await
la fonction attendra que l'opération asynchrone se termine (ou échoue) avant de continuer, sinon elle continuera immédiatement sans attendre.Il existe une autre solution pour cela si vous n'utilisez pas Native Promises mais Bluebird.
Vous pouvez également essayer d'utiliser Promise.map () , en mélangeant array.map et Promise.all
Dans votre cas:
la source
Promise.mapSeries
ouPromise.each
sont séquentiels, lesPromise.map
démarre tous en même temps.concurrency
option.Si vous mappez à un tableau de promesses, vous pouvez alors les résoudre toutes en un tableau de nombres. Voir Promise.all .
la source
Je recommanderais d'utiliser Promise.all comme mentionné ci-dessus, mais si vous avez vraiment envie d'éviter cette approche, vous pouvez faire une boucle for ou toute autre boucle:
la source
Solution ci-dessous pour traiter tous les éléments d'un tableau de manière asynchrone ET conserver l'ordre:
Codepen également .
Notez que nous n'attendons que Promise.all. Nous appelons calc sans "attendre" plusieurs fois, et nous collectons tout de suite un tableau de promesses non résolues. Puis Promise.all attend la résolution de tous et retourne un tableau avec les valeurs résolues dans l'ordre.
la source