【问题标题】:Google Maps API function does not return results in timeGoogle Maps API 函数未及时返回结果
【发布时间】:2014-07-22 17:33:06
【问题描述】:

所以我有一个具有以下属性的对象数组:AddressLatitudeLongitudeTitle

 poi("139 Main St", 0, 0, "Farmer's Market" ),
 poi("18 N Hopkins Ave", 37.4455, -143.7728, "YMCA" ),
 poi("42 Universe St", 37.4855, -143.8781, "Original Pizza #32" )

现在,第一个对象没有设置任何纬度和经度,所以我希望使用 Google 的 Geocode API 来填充缺失的数据。我在我的 API 密钥中包含了 API 脚本链接,它工作正常。

然后我创建了一个for 循环,该循环遍历数组并找到任何缺少数据的对象。它应该通过并用正确的信息替换任何空单元格。但是,尽管检索了信息,但它是在循环完成后才检索的。我可以安慰出正确的信息,但只有在函数返回空数据之后。

for (i=0; i < poiArray.length; i++ ) {
    var curr = poiArray[i];

    if ( !curr.lat || !curr.long ) {

        geocoder = new google.maps.Geocoder();
        geocoder.geocode( { 'address': curr.address }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                cur.lat = results[0].geometry.location.k;
                cur.long = results[0].geometry.location.B;
            } else {
                console.log('failed to include ' + curr.title);
                poiArray.splice(i--, 1);    
            }

       });  

    }

}

我尝试了timeout 和嵌套函数,但似乎没有任何效果。有什么建议么?


让我再提一点奇怪的事情:如果我在 for 循环中的 if (status == google.maps.GeocoderStatus.OK) { 变量 i 之后进行控制台,我每次都会得到数组的最后一个数字。如果我在加载来自 Google 的异步数据后控制台 poiArray,则循环似乎只会更新数组中的最后一项。

【问题讨论】:

  • 信息记录到控制台后,是否可以检查 poiArray 是否已更新?虽然 for 循环可能已经完成,但我 认为 应该更新变量。即使数据尚未更新,您的其余代码是否也开始运行?
  • 地理编码器是异步的。结果从服务器返回时从服务器返回。你可以用函数闭包来解决你的问题。
  • 您正在发出 异步 请求 - 当您到达当前循环迭代结束时,您还不能获得数据,这就是全部目的的回调函数。这对你来说是一本好书 - stackoverflow.com/questions/14220321/….
  • 为什么这个问题被否决了?这带来了一些非常有趣的观点。

标签: javascript google-maps for-loop geocode


【解决方案1】:

你可以用函数闭包来解决你的问题。此外,您不应使用 Google Maps Javascript API v3(.k、.B)的未记录属性,它们会随着 API 的更新而改变并破坏您的代码。

var geocoder = new google.maps.Geocoder();
function geocodeAddress(curr, i) {
  geocoder.geocode( { 'address': curr.address }, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
       cur.lat = results[0].geometry.location.lat();
       cur.long = results[0].geometry.location.lng();
    } else {
       console.log('failed to include ' + curr.title);
       poiArray.splice(i--, 1);    
    }
  });  
}
for (i=0; i < poiArray.length; i++ ) {
    var curr = poiArray[i];
    if ( !curr.lat || !curr.long ) {
        geocodeAddress(curr, i);
    }
}

【讨论】:

  • 这是否需要函数在进行下一次 for 循环迭代之前完成地理编码调用?如果是这样,它可能会因调用次数很少而使代码陷入困境
  • 辉煌。这非常有效,并且准确地显示了我在哪里装傻。感谢您也指出 .k .B 问题。
  • @wolffer-east:最终用户不会执行此脚本。管理员只会在蓝月亮中运行一次。在那种情况下,如果它有点密集有关系吗?
  • @invot 如果它在后端,你应该很高兴。我不确定延迟会是什么,只有当它正在触发 onload/doc 时才会担心
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 2016-08-07
  • 2014-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-12
相关资源
最近更新 更多