2012-01-30 44 views
2

我在循环中反复调用google api函数。 每次我想删除地址数组中的一个元素。javascript - google地理编码 - 关闭/循环问题

for(var i = 0; i < AddressObject.addressToArray.length; i++){    
    srPerformGeocode(AddressObject);  
    console.log(AddressObject.addressToArray); 
    AddressObject.addressToArray.splice(0, 1);     
} 
    // -------------------------------------------------------------- 
    // Perform geocoding 
    // -------------------------------------------------------------- 
    function srPerformGeocode(AddressObject) 
    {  
     address = AddressObject.addressToArray.join(","); 
     console.log(AddressObject.addressToArray);  
     if (geocoder){      
      geocoder.geocode({'address': address.trim() }, function (results, status) 
      {           
       if (status == google.maps.GeocoderStatus.OK){     
        console.log("geocoded " + AddressObject.addressToArray); 
             // Do something 
       } 
       else{     
        alert("FAIL"); 
       } 
      }); 
     } 
    } 

这似乎是发生的是,循环运行我的时间, 和功能srPerformGeocode运行每次我使用时间的 我循环的最后一个值。

['field1' ,'field2' ,'field3' ,'field4' ] 
['field1' ,'field2' ,'field3' ] 
['field1' ,'field2' ] 
['field1' ] 
geocoded field1 
geocoded field1 
geocoded field1 
geocoded field1 
+0

[Javascript闭合内部循环 - 简单实用示例]的可能重复(http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – rds 2013-01-17 17:56:22

回答

1

这不是一个闭合的问题,因为你从来没有真正关过任何变量(除srPerformGeocodeaddress,但这对你的问题无关紧要)。 Read more about what closures are here.

JavaScript passes objects by reference ,所以你周围传递的循环的每次迭代相同的阵列(和因而的srPerformGeocode每次调用)。

直到异步回调执行–地理编码服务称为与你在第一盘控制台输出看参数,但在执行回调,并在登录这实际上是精“的地理编码的......” ,因为在循环的最后一次迭代之后它才存在,所以只会看到AddressObject,因为循环很久以前就完成了(这是异步JavaScript的本质)。

解决您的问题的方法是通过的srPerformGeocode每次调用一个复制AddressObject阵列的。方便的是,数组有一个返回新数组的方法。 (splice只修改一个数组;它不创建一个新的。)

for (var i = 0; i < AddressObject.addressToArray.length; i++) {    
srPerformGeocode(AddressObject.slice(0, -i)); 
} 

(注意,这是一个浅拷贝;也就是说,阵列中的任何对象仍指向同一个对象作为原始数组这不要紧,在这里,因为你的阵列是满的原语)

其他一些注意事项:

  1. String.trim不能在IE ≤ 8存在的,所以你要address.trim()调用将抛出一个异常。
  2. 谷歌地图并不真正做批量地理编码;如果您进行过多的地理编码呼叫,您可能会发现自己的速度有限,甚至完全关闭。

1个学究会同意这种说法;请参阅linked答案。

+0

感谢您的耐心解释! – 2012-01-31 03:47:59

0

当您的回调被地理编码API调用时,AddressObject.addressToArray已被更改。你最好坚持你传递的字符串(而不是对象)。

我怀疑这会给你,你之后的结果:

console.log("geocoded " + address.trim());