web-dev-qa-db-fra.com

Chaîne promet avec AngularJS

J'ai un service appelé paymentStrategy qui est injecté dans mon contrôleur.

$scope.buy = function() {
  paymentStrategy.buy()
    .then(function(response) {

  }
}

Cette méthode d'achat de paymentStrategy déclenche plusieurs méthodes qui doivent être appelées séquentiellement. Lorsque toutes les méthodes de buy () sont terminées, alors () doit être appelé.

C'est probablement trivial mais je suis assez nouveau pour angulaire.

Pour le moment, buy (). Puis () est déclenché juste après les méthodes init (). J'ai le sentiment que nous devons mettre toutes ces méthodes dans un tableau de promesses et appliquer $ q.all ().

Toute aide ou suggestion serait grandement appréciée

angular.module('deps-app.payment.services', []).
  factory('paymentStrategy', function($q) {

 var deferred = $q.defer();
 var ITEM_TO_PURCHASE = "test.beer.managed";
 var promises = [];

 var handlerSuccess = function(result) {
      deferred.resolve(result);
  };

 var handlerError = function(result) {
      deferred.reject(result);
  };

 _init = function() {

     inappbilling.init(handlerSuccess, handlerError, { showLog:true }); 
     return deferred.promise;
    }

  _purchase = function() {
        inappbilling.buy(handlerSuccess, handlerError, ITEM_TO_PURCHASE);
        return deferred.promise;
  }

  _consume = function() {
        inappbilling.consumePurchase(handlerSuccess, handlerError, ITEM_TO_PURCHASE);
        return deferred.promise;
  }

return  {

     buy: function() {

      _init();
        .then(_purchase());
        .then(_consume());  

      return deferred.promise;                    
    }

 }
});
25

Faites toutes les méthodes atomar, en ajoutant leurs propres promesses. Dans votre code, le premier resolve complètera la totalité de la demande.

Si les méthodes ont leur propre promesse, vous pouvez les enchaîner facilement.

angular.module('deps-app.payment.services', []).factory('paymentStrategy', function($q) {
var ITEM_TO_PURCHASE = "test.beer.managed";

_init = function() {
  return $q(function (resolve, reject) {
    inappbilling.init(resolve, reject, { showLog: true }); 
  });
};

_purchase = function() {
  return $q(function (resolve, reject) {
    inappbilling.buy(resolve, reject, ITEM_TO_PURCHASE);  
  });
};

_consume = function() {
  return $q(function (resolve, reject) {
    inappbilling.consumePurchase(resolve, reject, ITEM_TO_PURCHASE);
  });
};

return  {
  // In this case, you don't need to define a additional promise, 
  // because placing a return in front of the _init, will already return 
  // the promise of _consume.
  buy: function() {    
    return _init()
      .then(_purchase)  
      // remove () from inside the callback, to pass the actual method 
      // instead the result of the invoked method.
      .then(_consume);      
  }    
};

});

19
Konstantin Krass

Si vous devez enchaîner des promesses dans Angular séquentiellement, vous pouvez simplement retourner les promesses de l'une à l'autre:

callFirst()
.then(function(firstResult){
   return callSecond();
})
.then(function(secondResult){
   return callThird();
})
.then(function(thirdResult){
   //Finally do something with promise, or even return this
});

Et si vous souhaitez renvoyer tout cela en tant qu'API:

function myMethod(){
   //Return the promise of the entire chain
   return first()
           .then(function(){
               return second();
           }).promise;
}
55
Josh