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();

英国にいるユーザーの入力からフォーマットされた住所を表示したい。しかし、2 番目のアラートが定義されていない理由がわかりません。最初の行で変数「fmtAdd」を定義していませんか?

4

1 に答える 1

1

「2番目の」アラートは、最初に実行されるため、実際には最初のアラートです(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()Google サーバーへの非同期リクエストを開始し、すぐに返します
  3. alert(fmtAdd); // says undefined;
  4. 非同期リクエストが完了し、コールバック関数を呼び出します
  5. コールバック関数セットfmtAddr

するべきこと

アプリケーションを正しい順序で実行します。

  • フォーマットされた住所でやりたいことを何でもする関数を作成します。
  • コールバックからこの関数を呼び出します。つまり、設定した後fmtAdd

(実際には、グローバル変数を使用せずに、フォーマットされたアドレスをパラメーターとしてこの関数に直接渡す方がよいでしょう)

于 2012-07-19T08:19:51.190 に答える