Angular JS等待所有承诺得到解决

时间:2017-01-10 13:59:18

标签: angularjs promise

循环遍历一个数组并对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;
}

提前致谢。

3 个答案:

答案 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