简体   繁体   English

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

[英]Handling multiple Ajax Requests inside another Ajax Request

I'm using angularjs' $http method to get multiple "parent" elements. 我正在使用angularjs的$ http方法来获取多个“父”元素。 In this Ajax Calls .success method, I have to iterate over the parent elements, and use yet another Ajax call for every parent element, to get its respective child elements. 在此Ajax Calls .success方法中,我必须遍历父元素,并对每个父元素使用另一个Ajax调用,以获取其各自的子元素。 What I want in the end, is an Array containing all the child element objects, so I can display them using ng-repeat. 最后,我想要的是一个包含所有子元素对象的Array,因此我可以使用ng-repeat显示它们。 That's why I want to collect all the child elements in an array first, and the write that array to the scope array I'm using to display, so angular will only update when all child elements are collected. 这就是为什么我要首先收集数组中的所有子元素,然后将该数组写入我要显示的作用域数组,所以angular仅在收集所有子元素时才会更新。 I'm not that versed in using promises, but I think this should be possible by using them. 我并不精通使用诺言,但是我认为使用诺言应该是可能的。 The structure is basically: 结构基本上是:

.success(function(parentElements){
                    var tempChildElements = [];
                    $.each(parentElements, function(i, parentElement){
                        getChildElements(parentElement)
                            .success(function(childElements){
                                tempChildElements.concat(childElements);
                            })
                        })
                    });
    $scope.childElements = tempChildElements;
});

Basically, I need to know when all the requests inside jQuery.each are finished. 基本上,我需要知道jQuery.each内部的所有请求何时完成。

EDIT: 编辑:

So, I changed my code to incorporate your answers, and I think I'm close but it's still not working. 因此,我更改了代码以合并您的答案,我认为我已经接近了,但仍然无法正常工作。 What I got is: 我得到的是:

$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);
            });
        };

EDIT 2: I got it to work using suggestions from you guys, below is my code. 编辑2:我得到了你们的建议,可以正常工作,下面是我的代码。 Feel free to share improvements. 随时分享改进。

$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;
        });
    });

}; };

Something like this might be a possibiliy. 这样的事情可能是可能的。 Loop through your parentElements calling getChildElements with that element. 遍历您的parentElements并使用该元素调用getChildElements However the response from getChildElements will be a promise if your returning the $http call so push that into an array and pass that array to $q.all . 但是,如果您返回$http调用,则getChildElements的响应将是一个保证,因此将其推入数组并将该数组传递给$q.all When all your ajax calls resolve so will $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();
        });

Most likely your ajax call won't be resolved by the time the array is passed to $q.all however another nice thing about promises is even if they are all resolved $q.all will resolve straight away instead. 您的ajax调用很可能在将数组传递给$q.all但是关于promise的另一个$q.all是,即使它们都已解决, $q.all也会立即解决。

See it in action. 看到它在行动。 http://jsfiddle.net/ht9wphg8/ http://jsfiddle.net/ht9wphg8/

Each request itself returns a promise, which can then be put into an array and pass that array to $q.all() . 每个请求本身都会返回一个$q.all() ,然后可以将其放入一个数组并将该数组传递给$q.all()

The success() callback is deprecated and since you need to return promises you need to use then() anyway in your original request callback. 不建议使用success()回调,并且由于您需要返回promise,因此无论如何都需要在原始请求回调中使用then()

Here's a sample factory that would make all the requests and once done you would have the parent data of first request returned to controller: 这是一个示例工厂,它将发出所有请求,完成后,您会将第一个请求的父数据返回给控制器:

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;
  });

});

DEMO DEMO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM