优雅地限制jQuery $().each的方法?

3
我正在尝试使用jQuery通过$().each输入,基于其中两个输入进行AJAX调用,并更新第三个输入。然而,AJAX调用(Google Maps反向地理编码)具有调用限制,意味着我必须每秒限制请求的数量。
我试图通过使用setTimeout来限制each的速度,每次迭代的超时时间增加2秒,但它只是一次性调用了所有函数。您认为我做错了什么吗?我的方法基于这个问题,但有些事情(特别是每次迭代中受影响的元素会改变)使得这个问题更加复杂。
<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个回答

1
你正在使用一个立即返回结果的函数来调用setTimeout。
请改为:
if($(this).find(".lat").val() == '' && $(this).find(".lng").val() == ''){
 var $current = $(this);
 setTimeout(function() { geocodeLocation($current)}, time);
 time += 2000;
}

同时也要看看 将参数传递给setTimeout的闭包 相关内容。

注意,在IE8 / Safari5中无法使用有用的 .bind 方法。


1
问题在于您正在调用函数geocodeLocation:
setTimeout( geocodeLocation($(this)), time);

相反,您只需要指向其标签。因此,它应该是:
setTimeout( geocodeLocation.bind(null, $(this)), time);

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

嗯,从未见过这种结构。看起来很有趣。我想知道为什么在控制台中看到一个数字对象而不是原始值...我将尝试使用jQuery集合 - 这样可以工作。太棒了 - http://jsfiddle.net/mplungjan/36d7b2ar/ - mplungjan
让我们在聊天中继续这个讨论。点击此处进入聊天室 - guest271314
Aha:bind 在 IE8 和 Safari5 中不受支持。 - mplungjan
不确定。我现在离开电脑了。 - mplungjan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接