A more graceful way to throttle jQuery's $ ().
I'm trying to use jQuery to $().each
through inputs, make an AJAX call based on two inputs, and update the third input. However, the AJAX call (reverse geocoding Google Maps) has a call limit, that is, I have to limit the number of requests I make per second.
I'm trying to disable each
by calling setTimeout with a timeout that increases by 2 seconds for each iteration, but it just calls them right away. Any ideas on what I am doing wrong? I'm basing my approach on this question , but a few things - especially the fact that the affected elements change with each iteration - make it a little trickier.
<button class="identify-locations">Identify locations</button>
<div class="row">
<input class="address"></input>
<input class="lat"></input>
<input class="lng"></input>
</div>
<!-- the same thing over again 30 times -->
<script>
$(".identify-locations").click(function(event){
var time = 2000;
$(".row").each(function(){
if($(this).find(".lat").val() == '' && $(this).find(".lng").val() == ''){
setTimeout( geocodeLocation($(this)), time);
time += 2000;
}
});
});
function geocodeLocation(object, time){
address = object.find(".address").val();
var geocoder = new google.maps.Geocoder();
geocoder.geocode({address: address},
function(results_array, status) {
if(status == 'OK'){
object.find(".lat").val( parseFloat(results_array[0].geometry.location.lat()) );
object.find(".lng").val( parseFloat(results_array[0].geometry.location.lng()) );
updateCount();
}
});
}
</script>
source to share
You call setTimeout with a function that returns the result immediately.
Instead of this
if($(this).find(".lat").val() == '' && $(this).find(".lng").val() == ''){
var $current = $(this);
setTimeout(function() { geocodeLocation($current)}, time);
time += 2000;
}
Also check Passing Parameters to Closure for setTimeout
Please note that useful .bind is not available in IE8 / Safari5
source to share