做一个循环而不是多个$http链接?

Do a loop instead of multiple $http chaining?

提问人:user7370387 提问时间:1/12/2017 最后编辑:user7370387 更新时间:1/13/2017 访问量:94

问:

对不起,我已经检查了答案,但仍然不明白如何制作:

我有一个数组:

 var surfaces   = [     
     {min:0,max:499},
     {min:500,max:999},
     {min:1000,max:1499},
     {min:1500,max:1999},
     {min:2000,max:2399},
     {min:2400,max:2999},
     {min:3000,max:3999},
     {min:4000,max:5999},
     {min:6000,max:100000}
 ]

我有这个 looong $http $q 的连锁电话:

 $q.when()  
    .then(function () { 
        $http.post('backend/backend.php?action=get_normes',surfaces[0]).success(function(data){
                $scope.normes.push(data);
        })
    })
    .then(function () { 
        $http.post('backend/backend.php?action=get_normes',surfaces[1]).success(function(data){
                $scope.normes.push(data);
        })
    })
    .then(function () { 
        $http.post('backend/backend.php?action=get_normes',surfaces[2]).success(function(data){
                $scope.normes.push(data);
        })
    })
    .then(function () { 
        $http.post('backend/backend.php?action=get_normes',surfaces[3]).success(function(data){
                $scope.normes.push(data);
        })
    })
    .then(function () { 
        $http.post('backend/backend.php?action=get_normes',surfaces[4]).success(function(data){
                $scope.normes.push(data);
        })
    })
    .then(function () { 
        $http.post('backend/backend.php?action=get_normes',surfaces[5]).success(function(data){
                $scope.normes.push(data);
        })
    })
    .then(function () { 
        $http.post('backend/backend.php?action=get_normes',surfaces[6]).success(function(data){
                $scope.normes.push(data);
        })
    })
    .then(function () { 
        $http.post('backend/backend.php?action=get_normes',surfaces[7]).success(function(data){
                $scope.normes.push(data);
        })
    })
    .then(function () { 
        $http.post('backend/backend.php?action=get_normes',surfaces[8]).success(function(data){
                $scope.normes.push(data);
        })
    })

我宁愿做一个循环,但现在知道如何做到这一点!

编辑:我有更大的问题:数据在$scope.normes中不按顺序排列!它总是不同的!我怎么能总是按顺序推动?数据怎么可能是有序的?

我得到了这样的 ng 重复,但由于同步性$http信息没有很好地排序;

<div class="row ">
                 <div class="col-lg-10" style="overflow: auto; max-height: 600px;">
                     <table  class="table table-bordered table-hover  " border="1" >
                        <thead >
                              <tr> 
                                <th> Désignation</th>
                                <th> Total Magasins</th>
                                <th> Moy Habitants Zone</th>
                                <th> Ca Moyen</th>
                                <th> EO Mini</th>
                                <th> EO Maxi</th>
                                <th> Coef Moyen</th>
                                <th> Pourcent Côtier</th>
                                <th> Pourcent Urbain</th>
                                <th> Tx Habituels</th>
                                <th> Tx fréquentation</th>
                                <th> Tx fidélisation</th>
                                <th> Zone Attraction</th>
                                <th> Revenus Zone</th>
                                <th> Nb Perso Foyer</th>
                                <th> Age Moyen</th>
                              </tr>
                        </thead>

                        <tbody >
                          <tr  ng-repeat="norme in normes" >
                             <td>Surface 0-499 m²</td>
                             <td>{{::norme.nb_magasins | number:0}}</td>
                             <td>{{::norme.moy_habitants_zone | number:0}}</td>
                             <td>{{::norme.ca_moyen | number:0}}</td>
                             <td>{{::norme.eomin | number:0}}</td>
                             <td>{{::norme.eomax | number:0}}</td>
                             <td>{{::norme.coef_moyen | number:2}}</td>
                             <td></td>
                             <td></td>
                             <td>{{::norme.tx_habituels | number:2}}</td>
                             <td>{{::norme.tx_frequentation | number:2}}</td>
                             <td>{{::norme.tx_fidelisation | number:2}}</td>
                             <td>{{::norme.attraction | number:0}}</td>
                             <td>{{::norme.revenus_zone | number:0}}</td>
                             <td>{{::norme.nb_pers_foyer | number:2}}</td>
                             <td>{{::norme.age_moyen | number:2}}</td>
                             <td ></td>
                          </tr>


                        </tbody>

                    </table>
                </div>

每次重做$q,它都会有不同的顺序!我该怎么办?

编辑:所以我现在从后端获取标准 JSON 对象,因此它更简单(编辑了这篇文章中的 html 表),但是使用您温和提供的解决方案,它还没有以正确的顺序出现。$http以正确的顺序开始,但似乎 $scope.normes 没有列出,因为$http已经开始了!(哦,我想我也许可以在前端使用 orderby 订购......我忘了,但我认为可以在 json 对象被推入数组时对它们进行排序,但在视图中,它不会像调用$http时那样出现)

angularjs json ajax

评论

0赞 Akram Saouri 1/12/2017
您可以使用 Angular 内置函数来处理多个异步 HTTP 调用forEach

答:

0赞 Pankaj Badukale 1/12/2017 #1

试试这个::

$scope.onAllDone = function() {
    var promises = [];

    angular.forEach(surfaces , function(surface) {
        promises.push($http.post('backend/backend.php?action=get_normes',surface)).then(function(data) {
            $scope.normes.push(data);
            return data;
        });
    });

    return $q.all(promises);
}

USE::

$scope.onAllDone().then(fnSuccess, fnError);

评论

0赞 user7370387 1/12/2017
非常感谢,我正在尝试。
0赞 user7370387 1/12/2017
对不起,我遇到了这个错误,错误:promises.push(...)。然后不是一个函数。但这似乎是一个很棒的代码,谢谢
0赞 digit 1/12/2017 #2

Promise 和 $q.all (doc) 是你的朋友。

更详细地说,您必须为每个调用做出承诺(如果调用本身没有返回一个),将它们推送到数组中并调用 $q.all(promises).then(allFinished)。

function callUpdate(x, promises) {
    var d = $q.defer();
    $http.post('backend/backend.php?action=get_normes',x).then(function(resp){
        $scope.normes.push(resp.data); 
        d.resolve(resp.data);
    })
    promises.push(d.promise);
}

...
var promises = [];
$scope.normes = [];
for (var i = 0; i < surfaces.length; i++) {
    callUpdate(surfaces[i], promises);
}

$q.all(promises).then(function() {
    // called when all promises have been resolved successully
});

评论

0赞 user7370387 1/12/2017
是的,它工作得很好,非常感谢!不幸的是,我没有以正确的顺序获得结果,每次都是以不同的顺序排列,我想是因为我正在对数组数组进行 ng-repeat 操作,以数字作为索引......它似乎每次都以不同的顺序涌入 $scope.normes 并给出不同的索引,我什至不明白如何,因为有一个承诺,应该以正确的顺序推动。
0赞 digit 1/12/2017
很高兴它有效。:).哦,你可以在 ng-repeat 中使用 orderBy 过滤器
0赞 digit 1/12/2017
您知道 $http.post 是异步的。所以,你永远不会知道哪个 1 是第一个完成的。您可以在获得所有结果后稍后订购。
0赞 user7370387 1/12/2017
好的,所以我现在尝试在我的后端创建对象而不是数组,这毫无意义,我将创建另一个关于这个问题的问题,因为我不知道如何在同一个表中对对象数组重复多次
0赞 Satpal 1/12/2017 #3

创建承诺数组

var promises = [];
surfaces.forEach(function(surface){
    promises.push($http.post('backend/backend.php?action=get_normes',surface));
}) 

您可以使用并等待所有 promise 完成,并使用 Array.concat() 创建数组。$q.all()$scope.normes

 $q.all(promises).then(function (results) {
    $scope.normes = [].concat.apply([],results);
});
0赞 georgeawg 1/12/2017 #4

链接 promise 时,请务必将后续 promise 返回给方法处理程序函数:.then

var arrayPromise = $q.when([])  
    .then(function (dArray) { 
        var httpPromise = $http.post('backend/backend.php/action=get_normes',surfaces[0])
        var dPromise = httpPromise.then(function(response) {
            $scope.normes.push(response.data);
            dArray.push(response.data);
            return dArray;
        });
        return dPromise;
    }).then(function(dArray) {
        console.log("one XHR is complete");
        console.log(dArray);
    });

当代码无法向处理程序函数返回任何内容时,$q服务会将 promise 解析为 并立即执行下一个函数。通过返回后续 Promise,$q 服务将等待 Promise 解析,然后再执行链中的下一个 Promise。undefined


可是。如何创建一个链接顺序承诺的循环?

var arrayPromise = $q.when([]);

for (let n=0; n<surfaces.length; i++) {  
    arrayPromise = arrayPromise
      .then(function (dArray) { 
        var httpPromise = $http.post(url,surfaces[n]);
        var dPromise = httpPromise.then(function(response) {
            $scope.normes.push(response.data);
            dArray.push(response.data);
            //return dArray to chain
            return dArray;
        });
        return dPromise;
    });
};

arrayPromise.then(function(dArray) {
    console.log("all XHRs are complete");
    console.log(dArray);
}).catch(function(errorResponse) {
    console.log("one of the XHRs failed");
    console.log(errorResponse.status);
    throw errorResponse;
});

创建一个具有空数组承诺的变量。然后,在循环中,只需将从方法派生的 promise 赋回该变量即可。循环的每次迭代都会返回一个数组,该数组比前一个迭代大一项。此外,每次迭代都有将项推送到作用域的副作用。.then