chaînes de rappel d'erreur promesse $ q

Dans l'extrait de code suivant error 1 et success 2 sera connecté. Comment puis-je propager les rappels d'erreur invoqués plutôt que les rappels de succès invoqués si l'original différé est rejeté.

angular.module("Foo", []);
angular
.module("Foo")
.controller("Bar", function ($q) {
    var deferred = $q.defer();
      deferred.reject();

      deferred.promise
          .then(
              /*success*/function () { console.log("success 1"); },
              /*error*/function () { console.log("error 1"); })
          .then(
              /*success*/function () { console.log("success 2"); },
              /*error*/function () { console.log("error 2"); });
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="Foo">
    <div ng-controller="Bar"></div>
</div>
24
demandé sur Steven Wexler 2014-10-18 20:49:28

3 réponses

L'erreur est propagée en retournant $q.reject dans le rappel d'erreur

    var deferred = $q.defer();
      deferred.reject();

      deferred.promise
          .then(
              /*success*/function () { console.log("success 1"); },
              /*error*/function () { console.log("error 1"); return $q.reject('error 1')})
          .then(
              /*success*/function () { console.log("success 2"); },
              /*error*/function () { console.log("error 2"); });
});
31
répondu Chandermani 2014-10-18 16:59:57

Pensez au succès / à l'échec comme à l'essai / à la capture

try{
    var val = dummyPromise();
} catch (e){
    val = "SomeValue";
}

Si catch ne lève pas d'exception, il est considéré que l'erreur est gérée et donc la fonction d'appel externe ne voit pas l'erreur qui s'est produite dans la fonction interne.

Des choses similaires qui se produisent ici, vous devez retourner return $q.reject(); d'une promesse pour que la prochaine promesse de la chaîne échoue aussi. Voir l'exemple plunker: http://plnkr.co/edit/porOG8qVg2GkeddzVHu3?p=preview

La raison est: votre erreur gestionnaire peut prendre des mesures pour corriger l'erreur. Dans votre fonction error - function votre traitement de l'erreur,si non spécifié autrement, il retournera une nouvelle promesse qui est résolue. Par conséquent, il n'est pas raisonnable d'avoir la promesse suivante échoue par défaut (analogie try-catch).

, Par la manière, vous pouvez retourner $q.reject(), même à partir d'un succès gestionnaire, si tu sens une condition d'erreur, la prochaine promesse de la chaîne d'échouer. Vous attrapez l'erreur et la manipulez-donc arrive au gestionnaire de succès. Si vous voulez le rejeter, vous devez le faire en retournant $Q. reject ();

14
répondu harishr 2016-11-22 05:34:56

Pour résumer les commentaires, pour propager les erreurs dans la chaîne de promesses, soit:

1) Ne pas fournir un errorCallback pour then:

deferred.promise
.then(
  /*success*/function () { console.log("success 1"); },
.then(
  /*success*/function () { console.log("success 2"); },
  /*error*/function () { console.log("error 2"); }); // gets called

Ou

2) Return $q.reject() de la errorCallback:

deferred.promise
.then(
  /*success*/function () { console.log("success 1"); },
  /*error*/function (err) { console.log("error 1"); return $q.reject(err); });
.then(
  /*success*/function () { console.log("success 2"); },
  /*error*/function () { console.log("error 2"); }); // gets called

À partir de la angulaire $Q. rejeter la documentation :

This api should be used to forward rejection in a chain of promises.
6
répondu user1338062 2015-09-11 19:26:58