How to run angularjs ajax request in a loop, but with a delay?

I need to run 20-200 ajax requests in a loop, but not damage google.maps.Geocoder I want to set a delay of 10 seconds between each call. However, the ajax request is asynchronous, so I call the next ajax request in response received after the previous one. If I get an answer too quickly, a delay must occur.

Here is the code that I have written so far:

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

So what's next?

You can add something like:

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

or do i have another way?

Thanks,

+4
source share
1 answer

This seems like a great use case for promises and $q .

This might look like a rough sketch of how to use promises. I am declaring a delay service for handling 10 second delay and a map service for processing geocoding. Both services return promises, and the controller can combine promises with $q.all() to ensure that there is at least 10 seconds between calls to the Google APIs.

 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(); }]); 
+7
source

Source: https://habr.com/ru/post/1479896/


All Articles