我有一个整数id数组,例如
var a=[1,2,3,4,5]
我需要为每个id执行异步远程调用。每个调用都是使用$ resource执行的WebAPI请求,并显示为promise。
我需要创建一个获取这些ID数组的函数,然后初始化递归promises链。该链应该逐个导致对每个ID进行相应的webapi调用。这些调用不应该是平行的,而应该是链接的。
有问题的函数会返回一个“主”承诺,应根据异步Web调用的结果解决或拒绝该承诺。也就是说,如果由于与服务器断开连接而导致递归中的某些承诺被拒绝,那么主承诺也应该失败。在正常情况下,“主要”承诺必须在所有请求完成时解决。
如何在angularjs中实现这一目标?
答案 0 :(得分:5)
您在数组上使用reduce
将承诺链接在一起。没有必要让这个递归。
// for angularjs: var Q = $q.when;
var p = a.reduce(function(prev, el) {
return prev.then(function(arr) {
return makeRequest(el).then(function(res) {
return arr.concat([res]);
});
});
}, Q([]));
答案 1 :(得分:2)
这实际上是一个非常合理的要求。
我们在没有特定.each
控件的库中使用的工具是.then
:
var a = [1,2,3,4,5];
var p = makeRequest(a.shift()); // use first element
a.forEach(function(el){
p = p.then(function(result){
return makeRequest(el);
});
});
p.then(function(){
// all requests done
});
请注意,我假设您在此处使用makeRequest
方法生成单个请求,并返回在请求完成时履行的承诺。
如果您需要使用辅助数组,也可以返回请求的结果:
var a = [1,2,3,4,5];
var results = Array(a.length);
var p = makeRequest(a.shift()).
then(function(res){ results[0] = res;}); // use first element
a.forEach(function(el,i){
p = p.then(function(result){
results[i] = result;
return makeRequest(el);
});
});
p = p.thenResolve(results); // resolve with results, in BB that'd be p.return(results)
p.then(function(results){
// all requests done
console.log(results); // array of response values
}).catch(function(e){
// single failure
});
使用Bluebird库的v2分支,您可以执行以下操作:
Promise.each([1,2,3,4,5],makeRequest).then(function(results){
// access results
});