如何在循环中运行angularjs ajax请求但延迟?

如何在循环中运行angularjs ajax请求但延迟?

问题描述:

我需要在循环中运行20-200个ajax请求,但不要伤害google.maps.Geocoder我希望在每次调用之间设置延迟10秒。然而ajax请求是异步的,因此我请求下一个ajax对前一个响应成功的请求。如果我的反应太快,应该延迟。如何在循环中运行angularjs ajax请求但延迟?

这里是我写到目前为止代码:

... 
$scope.addressList = ....; 
$scope.taskCount = $scope.addressList.length; 

geoTaskLoopAsync(); 

function geoTaskLoopAsync(){ 

    // on success douncount taskCount 
    var geo = new google.maps.Geocoder(); 
    geocoder.geocode({ 
    'address': address 
     }, function(results, status) { 
      $scope.$apply(function() { 
       // do something with response 

       if($scope.taskCurr <= $scope.taskCount){ 
       $scope.taskCurr++; 
       return geoTaskLoopAsync(); 
       } 

       return; 
      }); 
     }); 

那么下一步是什么?

我可以添加类似:

stop = $timeout(function() { 
     if($scope.taskCurr <= $scope.taskCount){    
      geoTaskLoopAsync(); 
     } else { 
      $timeout.cancel(stop); 
     }     
    }, 10000); 

或有我其他的方式?

谢谢

这似乎是一个很大的用例的承诺和$q服务。

下面是使用承诺可能看起来像什么的粗略草图。我宣布延迟服务来处理10秒延迟和地图服务来处理地理编码。两种服务都会返回承诺,并且控制器可以使用$q.all()合并承诺,以确保Google API调用之间至少有10秒的延迟时间。

angular.module(/* load your module */).service('delay', ['$q', '$timeout', function ($q, $timeout) { 
    return { 
     start: function() { 
      var deferred = $q.defer(); 
      $timeout(deferred.resolve, 10000); 
      return deferred.promise; 
     } 
    }; 
}]); 

angular.module(/* load your module */).service('maps', ['$q', function ($q) { 
    var geocoder = new google.maps.Geocoder(); 
    return { 
     geocode: function (address) { 
      var deferred = $q.defer(); 

      geocoder.geocode({ 
       'address': address 
      }, function (results, status) { 
       deferred.resolve(results); 
       // Should also reject if AJAX errors. 
      }); 

      return deferred.promise; 
     } 
    }; 
}]); 


angular.module(/* load your module */).controller('geocodingController', ['delay', 'maps', '$q', function (delay, maps, $q) { 
    var addresses = [/* An array of addresses to geocode */], 
     addressIndex = 0, 
     geocodeAddresses = function geocodeAddresses() { 
      // Use $q.all so that the callback will execute when the geocoding is done AND 10 seconds have passed. 
      $q.all([delay.start(), maps.geocode(addresses[addressIndex])]).then(function (results) { 
       addressIndex += 1; 
       var geocodedData = results[1]; // The geocode result is in the second index. 

       // Do something with the results. 

       if (addressIndex < addresses.length) { 
        geocodeAddresses(); 
       } 
      }); 
     }; 

    // Kick off the AJAX requests. 
    geocodeAddresses(); 
}]); 
+0

我以为你的'服务'实现像'工厂' – 2013-05-09 18:48:09