10
votes

Gestion des dépendances de promesse

J'utilise nœud.js et Bluebird pour créer une logique assez compliquée impliquant de décompresser un fichier structuré, analyse JSON, créer et apporter des modifications à plusieurs documents de MongoDB et écrire des fichiers associés dans plusieurs emplacements. J'ai également une manipulation relativement compliquée des erreurs pour tout cela en fonction de l'état du système lorsqu'une erreur se produit.

J'ai du mal à penser à un bon moyen de gérer les dépendances à travers le flux de promesses. p>

Mon code existant ressemble fondamentalement à ceci: p>

var doStuff = function () {
  var dependency1 = null;
  var dependency2 = null;

  promise1()
  .then(function (value) {
    dependency1 = value;

    return promise2()
    .then(function (value) {
      dependency2 = value;

      return promise3(dependency1)
      .then(successFunction);
    });
  })
  .catch(function (err) {
    cleanupDependingOnSystemState(err, dependency1, dependency2);
  });
};


3 commentaires

C'est probablement mieux pour les programmeurs.stackexchange.com d'être honnête homme.


Est-ce que promess2 dépend de promess1 ayant terminé? Le code implique que, mais c'est un peu flou.


Oui, toute promesse qui vient plus tard dépend de quelque chose d'une promesse antérieure et de données qu'elle a récupérée.


3 Réponses :


1
votes

Cette question peut être plus appropriée pour revue de code mais voici comment je l'approcher Cet exemple: xxx

L'utilisation de allResolved est uniquement à cause de vos spécificités de rappel, si vous aviez un gestionnaire d'erreur plus général, vous pouvez simplement résoudre en utilisant Promise.All directement, ou même: xxx


0 commentaires

1
votes

Ce n'est certainement pas un anticipé de retourner des promesses dans alors s, aplatissement des promesses imbriquées est une caractéristique de la spécificité de promesse.

Voici une réécriture possible, bien que je ne suis pas sûr que ce soit plus propre : xxx

ou une autre option, avec des fonctions de nettoyage atomique: xxx

vraiment, je me sens comme il n'y a pas beaucoup de choses que vous pouvez faire pour nettoyer cela. Événement avec vanille Essayez / Catch ES, le meilleur modèle possible est assez similaire à ceux-ci.


1 commentaires

Je suppose que je me suis senti comme si je me manque quelque chose sur les promesses, car la plupart des exemples de documentation sont la forme chaînée extrêmement propre.



11
votes

Je trouve les deux réponses actuellement fournies, bien mais maladroite. Ils sont tous les deux bons mais contiennent des frais généraux, je ne pense pas que vous ayez besoin d'avoir. Si vous utilisez plutôt des promesses en tant que proxy, vous obtenez beaucoup de choses gratuitement.

var doStuff = function () {
  var p1 = promise1();
  var p2 = p1.then(promise2);
  var p3 = p1.then(promise3); // if you actually need to wait for p2 here, do.
  Promise.join(p1, p2, p3, successFunction).catch(function(err){
      // clean up based on err and state, can unwrap promises here
  });
};


7 commentaires

Je pense que cela devrait être enfin pas attrape , sinon le nettoyage n'est pas effectué dans success


@Esailija son exemple original a attrapé, mais si c'est le nettoyage des ressources, je suis en accord, c'est la bonne façon de partir. Probablement mieux d'utiliser un modèle d'élimination ou encore mieux un réel .Dispose


C'est exactement le genre de solution que je cherchais, je n'avais pas envisagé d'enregistrer plusieurs rappels (cela semble si évident maintenant). J'ai beaucoup de refactoring à faire. Merci.


"// Si vous avez besoin d'attendre P2 ici, faites." S'il vous plaît élaborer?


@Nepoxx rien de beaucoup à ajouter - vous pouvez promess.join (p1, p2, promess3) Si vous devez aussi attendre P2 - je viens de supposer OP attendu mais je n'ai pas besoin de trop basé sur le Code de questions ci-dessus.


Je vois, merci pour la clarification. Cependant, ne serait-il pas préférable d'utiliser lid-kind de Bluebird pour passer des valeurs entre les appels chaînés?


@NEPOXX PAS si vous avez déjà le contexte - BIND a été conçu pour être plus d'une cale pour les fonctions fléchées 'Lexical Ceci (puisqu'il est plus rapide que ce que les gens font habituellement avec que qui nécessite une fermeture) . Vous pouvez certainement l'utiliser ici pour réussir le contexte - je préfère cette approche mais la liaison fonctionnerait aussi.