API 在 angular 中调用内部 for 循环

API call inside for loop in angular

我正在尝试创建一个 Ionic 应用程序,为此我必须在 for 循环中发出一些 HTTP GET 请求但是angular 似乎在显示数据之前没有等待数据。

这是我正在使用的代码。

$http.get(ApiUrl.get() + '/Threads' + '?access_token=' + $scope.userToken + filterString + "&filter[order]=created%20desc")
.success(function(data, status, headers, config) {

    var i=0;

    for(thread in data)
    {
        $scope.threadObj = data[i];
        var threadId = $scope.threadObj.id;
        $scope.threadPostNumber;

        //On récupére chaque nombre de post
        $http.get(ApiUrl.get() + '/Threads/' + threadId + '/posts/count' + '?access_token=' + $scope.userToken)
            .success(function(data, status, headers, config) {
                $scope.threadPostNumber = data.count;
            })
            .error(function(data, status, headers, config) {
                alert("Connection error, please try again.");
                $location.path("/app/carte");
            });

        $scope.threadObj.count = $scope.threadPostNumber;
        $scope.threads[i] = $scope.threadObj;

        i++;
    }
})
.error(function(data, status, headers, config) {
    alert("Connection error, please try again.");
    $location.path("/app/carte");
});

第一个 HTTP get 已完成,数据可以显示在 foreach 中,但是当我尝试使用第二个 get 请求将其他数据添加到原始数据时,没有创建任何内容或者有时只显示最后一个值。

问题源于 API 调用是异步的,比 for 循环慢得多。

$http.get 发布了请求,但直到 for 循环完成很长时间后才收到响应。因此,承诺成功回调中的 $scope.threadPostNumber 将在分配后设置:

$scope.threadObj.count = $scope.threadPostNumber

实际上这个赋值是没用的。

为了修复,使用尾递归或Promise objects 为了使调用连续。

您还可以适当地确定当前线程对象的范围,这样当 promise 成功时,您将修改正确的线程:

$http.get(ApiUrl.get() + '/Threads' + '?access_token=' + $scope.userToken + filterString + "&filter[order]=created%20desc")
.success(function(data, status, headers, config) {

    data.forEach(function(thread, i) {

        $scope.threads[i] = thread;

        var threadId = thread.id;

        $http.get(ApiUrl.get() + '/Threads/' + threadId + '/posts/count?access_token=' + $scope.userToken)
            .success(function(data, status, headers, config) {

                $scope.threads[i].count = data.count;
            })
            .error(function(data, status, headers, config) {

                alert('Connetion error, please try again.');
                $location.path('/app/carte');
            });
    });
})
.error(function(data, status, headers, config) {
    alert("Connection error, please try again.");
    $location.path("/app/carte");
});

因为这使用了 forEach (see the MDN page),threadi 的作用域是函数,所以对于该函数的生命周期以及它所包含的任何函数调用或创建(如 promise 成功回调),threadi 将保留传递给函数的值。这确保无论 HTTP 请求 return 的顺序如何,您都将在正确的线程上设置 count