在开始下一次循环迭代之前等待angularJS http服务完成

时间:2015-08-24 13:35:26

标签: angularjs

我写了一个自定义的http服务,看起来有点像这样:

.service('httpCaller', function ($http, $location) {

  var url = 'myURL'   

  var http = {

    async: function (api) {
        var promise = $http({
            method: 'GET',
            url: url + api,
            dataType: 'json'
        })
        .success(function (call) {
            return call;
        })
        .error(function () {
            $location.path('/search');
        });
        return promise;
    }

  };

  return http;

});

我需要在一个循环中调用这个服务大约一百次:

var results = [];
   for (var i = 0; i < someArray.length; i++) {
        httpCaller.async('myAPI').then(function (data) {
            results.push(data);
        });
    }
console.log(results);

显然我需要在开始下一次通话之前等待每个http通话完成,否则当我记录结果时#39;到了控制台,它总是空着因为呼叫尚未结束。我相信我需要使用......

$q.all()

...但我无法从Angular文档中找出如何将其与我编写的代码集成。谁能解释我需要怎么做呢?

2 个答案:

答案 0 :(得分:1)

您应该将所有承诺存储在一个数组中,并将其传递给$q.all函数。然后,您可以定义多个自动调用的回调。

这是一个例子。

var results = [],
    promises = [];

var promiseSuccess = function (data) {
    results.push(data);
};

var allSuccess = function (data) {
    //data contains array of all return values for promises
};

for (var i = 0; i < someArray.length; i++) {
    promises.push(httpCaller.async('myAPI').then(promiseSuccess));
}

$q.all(promises)
    .then(allSuccess) // called when everything has been loaded

答案 1 :(得分:1)

您可以使用延期API 中的 $ q.defer()承诺管理器。

$ q.defer()获取2种方法:

  • resolve(value):通过给她最终值来解决我们的相关承诺

  • 拒绝(原因):解决了承诺错误。

所以你可以将所有的promises存储在一个数组中,然后$q.all()用于创建一个promise,当作为参数传递的表的所有promise都将被解析时,它将被解析。

<强>控制器

(function(){

function Controller($scope, Service, $q) {

  var promises = [];

  var defer = $q.defer();

  //Process loop
  for (var i = 0; i < 20; ++i){
    //Fill my promises array with the promise that Service.get() return
    promises.push(Service.get());
  }

  //Resolve all promise into the promises array
  $q.all(promises).then(function(response){
    //Create arr by maping each data field of the response
    var arr = response.map(function(elm){
      return elm.data;
    });
    //Resolve my data when she is processed
    defer.resolve(arr);
  });

  //When the data is set, i can get it
  defer.promise.then(function(data){
    //Here data is an array
    console.log(data)
  });

}

angular
.module('app', [])
.controller('ctrl', Controller);

})();

<强>服务

(function(){

  function Service($http){

    function get(num){
      //Just an example, we return a promise
      return $http.get('path_to_url');
    }

    var factory = {
      get: get
    };

    return factory;

  }

  angular
    .module('app')
    .factory('Service', Service);

})();