一种更优雅的方式来限制jQuery $()。每个?

时间:2015-06-12 04:42:59

标签: javascript jquery ajax

我试图通过输入使用jQuery $().each,根据两个输入进行AJAX调用并更新第三个输入。但是,AJAX调用(谷歌地图反向地理编码)有一个呼叫限制,这意味着我必须限制每秒发出的请求数。

我试图通过调用setTimeout来限制each,每次迭代的超时时间增加2秒,但它只是一次调用它们。我对自己做错了什么的见解?我的方法基于this question,但是 一些事情 - 特别是受影响的元素随着每次迭代而变化的事实 - 使这更加复杂。

<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>

3 个答案:

答案 0 :(得分:1)

您正在使用一个立即返回结果的函数调用setTimeout。

取而代之的是

if($(this).find(".lat").val() == '' && $(this).find(".lng").val() == ''){
 var $current = $(this);
 setTimeout(function() { geocodeLocation($current)}, time);
 time += 2000;
}

另请查看Passing parameters into a closure for setTimeout

请注意,有用的.bind在IE8 / Safari5

中不可用

答案 1 :(得分:1)

问题是您在以下位置调用了函数geocodeLocation:

setTimeout( geocodeLocation($(this)), time);

相反,你应该只指向它的标签。因此,它应该是:

setTimeout( geocodeLocation.bind(null, $(this)), time);

答案 2 :(得分:1)

尝试使用index

.each()
 var time = 2000;
 $(".row").each(function(index){
   if($(this).find(".lat").val() == '' 
      && $(this).find(".lng").val() == '') {
        setTimeout(function() { 
          geocodeLocation($(this))
        }.bind(this), index * time);                    
   }
 });