循环遍历一个数组并对api进行异步调用返回的数据需要我合并一个不同的数组,当合并发生时问题面临的一些承诺尚未解析,因此合并后的结果数组缺少数据。任何想法如何去做。 (我是Angular的新手)。 循环的数组至少有200个元素(我事先不知道数组的大小)我得到每个元素的id,我称之为服务:
for (i = 0; i < list.length; i++) {
service.getRawHtml(list[i].service_object_id)
.then(function(res){
temp=htmlToArray(res);
htmlDataList.push(temp);
}, function(err){
// error
})
}
service.getRawHtml=function (id){
var defer = $q.defer();
$http({
method: 'GET',
url: 'http://wlhost:50000/'+id
}).success(function (response) {
defer.resolve(response);
}).error(function (data, status) {
console.log("Failure");
defer.reject(err);
});
return defer.promise;
}
提前致谢。
答案 0 :(得分:4)
使用$ q.all - 来自documentation:
将多个承诺合并到一个在何时解决的承诺中 所有的输入承诺都得到了解决。
使用示例:
$q.all([
getPromise(),
getPromise(),
getPromise()
]).then(function(value) {
$scope.result1 = value[0];
$scope.result2 = value[1];
$scope.result3 = value[2];
}, function(reason) {
$scope.result = reason;
});
答案 1 :(得分:2)
只是为了了解@nodes解决方案:
var promisesToWaitFor = [];
for (i = 0; i < list.length; i++) {
var promis = service.getRawHtml(list[i].service_object_id)
promisesToWaitFor.push(promis)
}
$q.all(promisesToWaitFor).then(function(resultsArray) {
var flatten = [].concat.apply([],resultsArray);
temp=htmlToArray(flatten);
htmlDataList.push(temp);
}, function(err) {
// error
});
答案 2 :(得分:2)
正如@ndoes建议的那样,这可以通过$q.all()
来完成,$q.all()
会获得一系列承诺,并在所有这些承诺得到解决时解决,或者如果其中任何一个被拒绝则拒绝。
您正在执行将要执行的for循环中的异步函数,但是一旦完成所有函数调用,代码将继续同步。所有的决定都不会有任何神奇的等待。
你应该做的是将所有返回的promises推送到一个数组,然后使用//Declare an array to which we push the promises
var promises = [];
for (i = 0; i < list.length; i++) {
//Call the service and push the returned promise to the array
promises.push(service.getRawHtml(list[i].service_object_id));
}
//Await all promises
$q.all(promises)
.then(function(arrayOfResults){
//Use your result which will be an array of each response after
//it's been handled by the htmlToArray function
})
.catch(function(err){
//Handle errors
});
等待它们。
$http
我借此机会同时重构您的代码,因为它正在实施deferred anti-pattern。由于service.getRawHtml = function (id){
return $http({
method: 'GET',
url: 'http://wlhost:50000/'+id
}).success(function (response) {
return htmlToArray(response);
}).error(function (data, status) {
console.log("Failure");
$q.reject(error);
});
}
已经返回承诺,因此无需创建和返回新承诺。只需像
play_hosts