AngularJS链在for循环中顺序承诺

时间:2016-12-21 22:29:57

标签: javascript angularjs promise

我如何在for循环中按顺序链接promises,我在google上看到很多例子来做这个但我无法实现我的情况: 我已经通过这个link来对Promises进行顺序链接。

我想要实现的目标:
Promise1:login();
Promise2:sync();

sync函数调用另一个服务complete()以获取元素数组。这些元素数组必须按顺序完成。

ServiceA.login().  
      then(function(response){
                   ServiceA.sync()
                        .then(function(response){

                         })
      })

function sync(){
     ServiceB.complete()
                    .then(function(){
                               var promises = [];
                               angular.forEach(response, function (value) {
                    // The below service call doSomething() must be done sequentially for each "value"
                                  promises.push(doSomething(value));
                               });
                               $q.all(promises).then(function () {


                                        });
                                    });

                      })
}

如何捕获每个Promise中发生的错误?

更新
我尝试过@zaptree建议的方法,代码如下:

ServiceA.login()
.then(function(response){
    // you must always return your promise
    return ServiceA.sync()

})
// don't nest the .then make them flat like this
.then(function(response){

})
.catch(function(){
    // if you made sure to always return your promises this catch will catch any errors throws in your promise chain including errors thrown by doSomething()
});

function sync(){
// you must always return your promise
return ServiceB.complete()
    .then(function(){

        var result = $q.when();
        angular.forEach(response, function (value) {
            result = result.then(doSomething(value)); // problem is here that doSomething function is being called before the first call it is resolved
// doSomething is a http call.
        });
        return result;
    })
    .then(function(){
        // the array of promises has run sequentially and is completed
    });

}

 function doSomething(data){
      return $http({
            method: 'POST',
            url: '/api/do',
            data: data,
            headers: {
                "Content-Type": "application/json"
            }
        }).then(function (response) {

        }, function (error) {

        });
  }

如果每个循环附近的响应中有2个值(valuea,valueb),则代码表现如下:
1.调用doSomething(valuea)
2.在解决上述承诺之前调用doSomething(valueb) 预期行为:
在POST方法通过调用doSOmething(valuea)成功完成之后,另一个POST调用应该发生,即soSomething(valueb)。

2 个答案:

答案 0 :(得分:2)

这就是我想出的。您需要将数组减少为单个承诺。

var results = [...];
var sequentialPromise = results.reduce(function(a, b) {
  return a.then(function(){
   return doSomething(b);
  });
}, $q.resolve());

sequentialPromise.then(function(){...});

答案 1 :(得分:0)

所以这里有一个关于如何使用Q执行顺序承诺的示例,还有一些关于如何执行承诺的改进,以便您可以正确捕获承诺链中任何点处抛出的错误。您必须始终确保在使用它们的任何方法上返回承诺。也可以通过不嵌套.then来避免金字塔代码,以使代码更清晰:

ServiceA.login()
    .then(function(response){
        // you must always return your promise
        return ServiceA.sync()

    })
    // don't nest the .then make them flat like this
    .then(function(response){

    })
    .catch(function(){
        // if you made sure to always return your promises this catch will catch any errors throws in your promise chain including errors thrown by doSomething()
    });

function sync(){
    // you must always return your promise
    return ServiceB.complete()
        .then(function(){

            var result = $q.when();
            angular.forEach(response, function (value) {
                result = result.then(doSomething(value));
            });
            return result;
        })
        .then(function(){
            // the array of promises has run sequentially and is completed
        });

}