Javascript AngularJS链在for循环中按顺序承诺

Javascript AngularJS链在for循环中按顺序承诺,javascript,angularjs,promise,Javascript,Angularjs,Promise,如何在for循环中按顺序链接承诺,我在谷歌上看到了很多这样做的例子,但我无法在我的案例中实现: 我已经经历了这一连串的承诺 我想说的是: 承诺1:登录() 承诺2:sync() sync函数为元素数组调用另一个service complete()。这些元素数组必须按顺序进行 ServiceA.login(). then(function(response){ ServiceA.sync() .t

如何在for循环中按顺序链接承诺,我在谷歌上看到了很多这样做的例子,但我无法在我的案例中实现: 我已经经历了这一连串的承诺

我想说的是:
承诺1:登录()
承诺2:sync()

sync函数为元素数组调用另一个service 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 () {


                                        });
                                    });

                      })
}
如何捕捉每个承诺中出现的错误

更新:
我用以下代码尝试了@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
    });
}

如果for each循环附近的响应中有2个值(valuea、valueb),则代码的行为如下:
1.调用doSomething(valuea)
2.在上述承诺得到解决之前调用doSomething(valueb)。
预期行为:

在POST方法通过调用doSOmething(valuea)成功完成后,应该会发生另一个POST调用,即soSomething(valueb)

这是我想到的。您需要将阵列简化为一个承诺

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

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

下面是一个关于如何使用Q实现连续承诺的示例,还有一些关于如何实现承诺的改进,这样您就可以正确地捕获承诺链中任何一点抛出的错误。您必须始终确保对使用它们的任何方法返回承诺。还可以通过不嵌套来避免金字塔代码。然后,要使代码更干净,请执行以下操作:

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

}

为什么按顺序?它们相互依赖吗?是的,它们相互依赖。
$q.all([…])
如果其中一个失败,它们将失败,但它们并行运行。为了按顺序运行,您必须通过
链接它们。然后()
。在您正在构建的承诺链上,这不是
doSomething()
吗。其他的一个只有在回调调用IE时才会发生-前面的承诺已经完成。也许我遗漏了什么,但是在
reduce
的第一个循环中,
a
不是一个已解决的承诺吗?不
reduce
需要返回
a.then(function(){return doSomething(b)})?这是否适用于服务?或者它对工厂和服务都有效吗?这将有效,但是您需要在
中指定回调函数。然后()
我在
var result=$q()附近遇到错误我在我的函数中注入了类似于
ServiceB.inject=['$q']
。控制台中的错误:
TypeError:[$q:norslvr]预期的resolverFn,得到了“未定义的”
hmm看起来$q需要一个解析程序,这很愚蠢:你可以做$q。我相信是when()。
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
        });

}