1
var geocoder, map, point, fmtAdd, marker;

function mapLoad() {
geocoder = new google.maps.Geocoder();
var myOptions = {
  zoom: 15,
  mapTypeControl: false, 
  mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map"), myOptions);
address="W3 6BY";
if(address){geocoder.geocode({'address':address}, geocodeResult);}
else{alert("Postcode Incorrect");window.close();}
}

function geocodeResult(results, status) {
if (status == 'OK' && results.length > 0) {
    point=results[0].geometry.location;
    map.setCenter(point);
    marker = new google.maps.Marker({map: map, position: point, draggable: true});
    geocoder.geocode({latLng:point},function(results, status){
          if(status == 'OK') {
            if(results.length == 0) {
            fmtAdd = 'None';
            } else {
            fmtAdd = results[0].formatted_address;
            }
          } else {
            fmtAdd = 'Error';
          }
          alert(fmtAdd); // shows the address
        });
          alert(fmtAdd); // says undefined;
} else {
  alert("Error: " + status);
}
}
mapLoad();

我想显示来自英国用户输入的格式化地址。但我不明白为什么第二个警报未定义?我不是在第一行定义了变量“fmtAdd”吗?

4

1 回答 1

1

您的“第二个”警报实际上是您的第一个警报,因为它首先执行(geocode()非阻塞 - 它立即返回)。
那时你“定义”fmtAdd了,但你没有初始化它。

var foo; alert(foo);

警报undefined


回复评论:

我认为它是一个全局变量,一旦地理编码给它一个值,我甚至可以从地理编码函数中检索该值。

这是对的。geocode()一旦传递给它的回调函数设置了一个值,该变量就会被初始化。正是这种情况发生了。那个“事件”之后,您也可以在函数之外从全局变量中检索值。

这里的问题是您试图在回调函数完成(甚至被调用)fmtAddr 之前检索值。
这是因为geocode()是非阻塞的。这意味着它会立即返回,这就是您将回调函数传递给geocode().

发生什么了

参考这部分代码:

geocoder.geocode({ latLng: point }, function (results, status) {
    if (status == 'OK') {
        if (results.length == 0) {
            fmtAdd = 'None';
        } else {
            fmtAdd = results[0].formatted_address;
        }
    } else {
        fmtAdd = 'Error';
    }
    alert(fmtAdd); // shows the address
});
alert(fmtAdd); // says undefined;

按年代顺序:

  1. 你打电话geocode(),向它传递一个回调
  2. geocode()向谷歌服务器发起异步请求并立即返回
  3. alert(fmtAdd); // says undefined;
  4. 异步请求完成并调用您的回调函数
  5. 你的回调函数集fmtAddr

你需要做什么

以正确的顺序执行您的应用程序:

  • 创建一个函数,它可以对格式化的地址执行任何操作。
  • 从您的回调中调用此函数。也就是说,在你设置之后fmtAdd

(实际上最好将格式化的地址作为参数直接传递给这个函数,而不使用全局变量)

于 2012-07-19T08:19:51.190 回答