2013-05-09 2 views
4

Мне нужно запустить 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); 

или я другой путь?

Спасибо,

ответ

7

Это кажется большим прецедентом для обещаний и сервиса $q.

Вот приблизительный эскиз того, как могут выглядеть обещания. Я объявляю службу задержки для обработки 10-секундной задержки и службы карт для обработки геокодирования. Обе службы возвращают обещания, и контроллер может объединить обещания с использованием $q.all(), чтобы гарантировать, что между вызовами API Google существует как минимум 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

Я думал, что ваша реализация 'service' как' factory' –

Смежные вопросы