Javascript 在另一个Ajax请求中处理多个Ajax请求

Javascript 在另一个Ajax请求中处理多个Ajax请求,javascript,jquery,ajax,angularjs,Javascript,Jquery,Ajax,Angularjs,我使用angularjs的$http方法来获取多个“父”元素。在这个Ajax Calls.success方法中,我必须迭代父元素,并对每个父元素使用另一个Ajax调用,以获得其各自的子元素。最后,我想要的是一个包含所有子元素对象的数组,这样我就可以使用ng repeat显示它们。这就是为什么我想首先收集数组中的所有子元素,然后将该数组写入我用来显示的作用域数组,因此angular只会在收集所有子元素时更新。我不太擅长使用承诺,但我认为使用承诺应该是可能的。结构基本上是: .success(fun

我使用angularjs的$http方法来获取多个“父”元素。在这个Ajax Calls.success方法中,我必须迭代父元素,并对每个父元素使用另一个Ajax调用,以获得其各自的子元素。最后,我想要的是一个包含所有子元素对象的数组,这样我就可以使用ng repeat显示它们。这就是为什么我想首先收集数组中的所有子元素,然后将该数组写入我用来显示的作用域数组,因此angular只会在收集所有子元素时更新。我不太擅长使用承诺,但我认为使用承诺应该是可能的。结构基本上是:

.success(function(parentElements){
                    var tempChildElements = [];
                    $.each(parentElements, function(i, parentElement){
                        getChildElements(parentElement)
                            .success(function(childElements){
                                tempChildElements.concat(childElements);
                            })
                        })
                    });
    $scope.childElements = tempChildElements;
});
基本上,我需要知道jQuery.each中的所有请求何时完成

编辑:

所以,我改变了我的代码,加入了你的答案,我想我很接近了,但它仍然不起作用。我得到的是:

$scope.loadChildren = function(){
            var tempchildren = [];
            var promises = [];
            restApi.getOwnparents() //Returns $http.get promise
                .then(function(parents){

                    parents.data.forEach(function(parent, i, parents){
                        promises.push(restApi.getOwnchildren(parent) //Returns $http.get promise
                            .then(function(children){

                                tempchildren = tempchildren.concat(children.data);
                            },function(msg){
                                console.log(msg);
                            }));

                    });
                }, function(msg){
                    console.log(msg);
                });
            $q.all(promises).then(function(data){
                //Never gets called
                $scope.currentElements = tempchildren;
                console.log(tempchildren);
            });
        };
编辑2: 我使用你们的建议来实现它,下面是我的代码。请随意分享改进

$scope.loadparents = function(){
var tempchildren = [];
var promises = [];
restApi.getOwnparents()
    .then(function(parents){
        parent.data.forEach(function(parent, i, parents){
            promises.push(restApi.getOwnchildren(parent));             
        });
        $q.all(promises).then(function(data){
            console.log(data);
            data.forEach(function(children){
                tempchildren = tempchildren.concat(children.data);
            });
            $scope.currentElements = tempchildren;
        });
    });

})

像这样的事情可能会发生。循环使用该元素调用
getChildElements
。但是,如果您返回
$http
调用,则来自
getChildElements
的响应将是一个承诺,因此将其放入数组并将该数组传递给
$q.all
。当所有ajax调用都解决时,
$q.all

 var parentElements = [10, 20, 30, 40],
        promises = [];

    parentElements.forEach(function(i){
        //Each method is actually called here
        promises.push(getChildElements(i));
    });

    //$q.all will resolve once all of your promises have been resolved.
    $q.all(promises)
        .then(function (data){
            //handle success
            console.log('All Good', data);
            //Modify your response into what ever structure you need, map may be helpfull
            $scope.childElements = data.map();
        });
最有可能的是,当数组传递给
$q.all
时,您的ajax调用将不会得到解决。但是,承诺的另一个好处是,即使它们都已解决
$q.all
也会立即得到解决


看到它在行动

每个请求本身都返回一个承诺,然后可以将该承诺放入一个数组中,并将该数组传递给
$q.all()

success()
回调已被弃用,因为您需要返回承诺,所以您需要在原始请求回调中使用
then()

下面是一个示例工厂,它将发出所有请求,完成后,您将第一个请求的父数据返回给控制器:

app.factory('DataService', function($http, $q) {
  return {
    getData: function() {
      // return initial promise
      return $http.get('parent.json').then(function(resp) {
        var parentArr = resp.data;
        // create array of promises for child data
        var promises = parentArr.map(function(parentItem, i) {
          // return each child request promise to the array
          return $http.get('child.json').then(function(resp) {
            console.log('Child request #' + (i + 1) + ' completed');
            // update parent item
            parentItem.child = resp.data
          });
        });
        // return the promise wrapping array of child promises
        return $q.all(promises).then(function() {
          console.log('All requests completed');
          // when all done we want the parent array returned
          return parentArr;
        });
      });
    }
  };
});

app.controller('MainCtrl', function($scope, DataService) {
  DataService.getData().then(function(parentArr) {
    console.log('Add data to scope')
    $scope.parentArr = parentArr;
  });

});

首先去掉
$,如果
parentelements
是一个数组,则可以使用本机
forEach
,否则使用
angular.forEach
。查看
$q.all
一旦所有承诺都解决了,它将运行一系列承诺,然后调用它的