2013-05-09 132 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()合併承諾,以確保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