我如何在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)。
答案 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
});
}