J'ai un tableau comme une structure qui expose les méthodes asynchrones. La méthode async appelle des structures de tableau de retour qui à leur tour exposent plus de méthodes async. Je crée un autre objet JSON pour stocker les valeurs obtenues à partir de cette structure et je dois donc faire attention au suivi des références dans les rappels.
J'ai codé une solution de force brute, mais j'aimerais apprendre une solution plus idiomatique ou plus propre.
- Le modèle doit être répétable pour n niveaux d'imbrication.
- Je dois utiliser promise.all ou une technique similaire pour déterminer quand résoudre la routine englobante.
- Tous les éléments n'impliqueront pas nécessairement de faire un appel asynchrone. Donc, dans une promesse imbriquée.all, je ne peux pas simplement attribuer des éléments à mes éléments de tableau JSON en fonction de l'index. Néanmoins, je dois utiliser quelque chose comme promise.all dans le forEach imbriqué pour m'assurer que toutes les attributions de propriété ont été effectuées avant de résoudre la routine englobante.
- J'utilise la librairie bluebird promise mais ce n'est pas une exigence
Voici un code partiel -
var jsonItems = [];
items.forEach(function(item){
var jsonItem = {};
jsonItem.name = item.name;
item.getThings().then(function(things){
// or Promise.all(allItemGetThingCalls, function(things){
things.forEach(function(thing, index){
jsonItems[index].thingName = thing.name;
if(thing.type === 'file'){
thing.getFile().then(function(file){ //or promise.all?
jsonItems[index].filesize = file.getSize();
javascript
node.js
asynchronous
promise
user3205931
la source
la source
Promise.map
(simultané) etPromise.each
(séquentiel) dans ce cas, également la notePromise.defer
est obsolète - le code dans ma réponse montre comment l'éviter en renvoyant des promesses. Les promesses concernent toutes les valeurs de retour.Réponses:
C'est assez simple avec quelques règles simples:
then
, renvoyez-la - toute promesse que vous ne reviendrez pas ne sera pas attendue à l'extérieur..all
elles - de cette façon, il attend toutes les promesses et aucune erreur de l'une d'entre elles ne sera réduite au silence.then
, vous pouvez généralement revenir dans le milieu - lesthen
chaînes ont généralement au plus 1 niveau de profondeur.Et quelques conseils:
.map
qu'avecfor/push
- si vous mappez des valeurs avec une fonction,map
vous permet d'exprimer de manière concise la notion d'application des actions une par une et d'agréger les résultats.Promise.all
que d'exécuter les choses l'une après l'autre - chacune attendant avant la suivante.Ok, alors commençons:
la source
Voici un exemple simple d'utilisation de réduire. Il fonctionne en série, maintient l'ordre d'insertion et ne nécessite pas Bluebird.
Et utilisez-le comme ceci:
Nous avons trouvé utile d'envoyer un contexte facultatif en boucle. Le contexte est facultatif et partagé par toutes les itérations.
Votre fonction de promesse ressemblerait à ceci:
la source
J'ai traversé la même situation. J'ai résolu en utilisant deux Promise.All ().
Je pense que c'était vraiment une bonne solution, alors je l'ai publiée sur npm: https://www.npmjs.com/package/promise-foreach
Je pense que votre code sera quelque chose comme ça
la source
Juste pour ajouter à la solution présentée, dans mon cas, je voulais récupérer plusieurs données de Firebase pour une liste de produits. Voici comment je l'ai fait:
la source