【问题标题】:Chain promises with AngularJSAngularJS 的链式承诺
【发布时间】:2014-08-12 23:49:37
【问题描述】:

我有一个名为 paymentStrategy 的服务被注入到我的控制器中。

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

  }
}

paymentStrategy 中的这个 buy 方法会触发几个需要按顺序调用的方法。当 buy() 中的所有方法都完成后,需要调用 then()。

这可能是微不足道的,但我对 Angular 还是很陌生。

目前,buy().then() 会在 init() 方法之后直接触发。 我觉得我们需要将所有这些方法放在一系列 Promise 中并应用 $q.all()。

任何帮助或建议将不胜感激

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;                    
    }

 }
});

【问题讨论】:

  • init、buy、consumePurchase等inappbilling的所有方法都返回promise吗?
  • 听起来不错,但您能说明一下方法吗?
  • 这是向你提出的问题 Florent。您的代码的问题是您在 init 回调和其他回调上也解决了 Promise,但是您需要等待所有调用完成,然后再调用 resolve。
  • 前两个参数 handlerSuccess 和 handlerError 是在方法(init、buy 和 consumePurchase)完成时调用的回调。即,仅当调用了 init(...) 中的 handlerSuccess 时才需要调用 _purchase()。 _consume 仅在调用了 purchase(...) 中的 handlerSuccess 时才需要调用。

标签: javascript angularjs promise chaining


【解决方案1】:

如果您需要在 Angular 中按顺序链接 Promise,您可以简单地将 Promise 从一个返回到另一个:

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

如果您想将所有这些作为 API 返回:

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

【讨论】:

  • 我是新来的承诺和角度。这里第一个 then return 调用 second then 但它正在返回方法,实际上 second 然后将值作为参数对。我只知道 C 所以我不确定。
  • 如此简单,如此强大!谢谢你。只有在阅读了您的帖子后,我才明白我必须做什么。我发现的所有其他示例都非常复杂。
  • 这是正确的方法。 'return' 是必需的,否则这将不起作用。
【解决方案2】:

通过添加自己的 Promise 使所有方法成为原子。在您的代码中,第一个 resolve 将完成整个请求。

如果方法有自己的承诺,您可以轻松地将它们链接起来。

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);      
  }    
};

});

【讨论】:

  • 非常感谢您的帮助,非常感谢。接受之前的一个问题。似乎它永远不会在 buy() 方法中进入 then(..) 。这样做是个好方法吗? : _init() .then(_consumeAll) .then(_purchase) .then(_consume) .then(deferred.resolve)
  • 啊我的错。立即查看
  • 使用$q.defer()就是almost always bad practice,这也不例外。这三个函数中的每一个都可以通过执行类似_init = function() { return $q(function(resolve, reject) { inappbilling.init(resolve, reject, { showLog: true }); }); }; 的操作来简化,这将根据需要返回一个承诺。理想情况下,inappbilling 上的方法应该返回承诺(由您的 _init 等方法简单地返回),但我想这可能不是您的决定。
  • @Sean the Bean 是对的。 @ 2014 这对我来说是唯一正确的答案,直到我发现 return $q. 例程。
猜你喜欢
  • 1970-01-01
  • 2013-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-16
  • 1970-01-01
  • 2016-06-18
  • 1970-01-01
相关资源
最近更新 更多