вопрос о глобальной переменной javascript - PullRequest
1 голос
/ 16 июля 2009
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example: Simple Streetview Example</title>
<script src="http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=<?=APIKEY?>"
        type="text/javascript"></script>
<script type="text/javascript">

var myPano;
var newPoint;

function initialize() {
  var fenwayPark = new GLatLng(42.345573,-71.098326);
  var address = "1600 Amphitheatre Parkway, Mountain View, CA, USA";

  var geocoder = new GClientGeocoder();
    geocoder.getLatLng(
        address,
        function(point) {
            if (!point) {
                alert(address + " not found");
            } else {
                newPoint = point;
                alert("inside of function: " + newPoint);
            }
        });
    alert("outside of function: " + newPoint);
  panoramaOptions = { latlng:fenwayPark };
  myPano = new GStreetviewPanorama(document.getElementById("pano"), panoramaOptions);
  GEvent.addListener(myPano, "error", handleNoFlash);
}

function handleNoFlash(errorCode) {
  if (errorCode == FLASH_UNAVAILABLE) {
    alert("Error: Flash doesn't appear to be supported by your browser");
    return;
  }
}  
</script>

когда я запускаю этот код, появляется предупреждение («вне функции:» + newPoint); не имеют никакого значения, кроме как в функции alert ("внутри функции:" + newPoint); это получает.

полный код:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example: Simple Streetview Example</title>
<script src="http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=ABQIAAAAgVzm2syhpm0A5rAKFMg3FBS-DTtkk0JB-Y_gKL-3MRZwBHch9RSjWJj17-fEEecjCvYeo1i7w_1yPw"
        type="text/javascript"></script>
<script type="text/javascript">

var myPano;

function initialize() {

    var geocoder = new GClientGeocoder();

    var address = "1600 Amphitheatre Parkway, Mountain View, CA, USA";
    geocoder.getLatLng(
        address,
        function(point) {
        if (!point) {
            alert(address + " not found");
        } else {
            panoramaOptions = { latlng:point };
            myPano = new GStreetviewPanorama(document.getElementById("pano"), panoramaOptions);
            GEvent.addListener(myPano, "error", handleNoFlash);
        }
    });
}

function handleNoFlash(errorCode) {
  if (errorCode == FLASH_UNAVAILABLE) {
    alert("Error: Flash doesn't appear to be supported by your browser");
    return;
  }
}  
</script>

Я хочу показать при просмотре страницы адрес улицы: 1600 Amphitheatre Parkway, Mountain View, CA, USA

Ответы [ 4 ]

4 голосов
/ 16 июля 2009

Внутренняя функция является функцией обратного вызова. Это означает, что он ожидает завершения вызова API геокодирования, прежде чем он будет выполнен. Это известно как асинхронное выполнение. Вы заметите, что внешнее оповещение срабатывает раньше, чем внутреннее оповещение, даже если внутреннее оповещение написано ранее.

Любой код, для которого требуется действительное значение newPoint, необходимо будет выполнить из функции обратного вызова, так же как и изнутри.

3 голосов
/ 16 июля 2009

getLatLng() является асинхронным.

Вы звоните getLatLng(), а через некоторое время он перезванивает с данными. Ваш код «вне функции» вызывается сразу после вашего вызова getLatLng(), до , когда происходит асинхронный вызов вашего «внутреннего вызова функции».

1 голос
/ 16 июля 2009

Вы исправили проблему с асинхронным getLatLng(). Единственная проблема с вашим новым кодом состоит в том, что по указанному вами адресу нет панорамы (выведите «1600», и он будет работать). Есть функция, которая возвращает точку ближайшей панорамы: getNearestPanoramaLatLng () . Он вернет ноль, если рядом нет панорамы. Вот как это использовать в вашем коде:

function initialize() {

    var geocoder = new GClientGeocoder();
    var panoClient = new GStreetviewClient();

    var address = "1600 Amphitheatre Parkway, Mountain View, CA, USA";

    geocoder.getLatLng(
    address,
    function(point) {
        if (!point) {
            alert(address + " not found");
        } else {
            panoClient.getNearestPanoramaLatLng(point, function(newPoint) {
                if (newPoint == null) {
                    alert("no panorama found");
                    return;
                }
                panoramaOptions = { latlng:newPoint};
                myPano = new GStreetviewPanorama(document.getElementById("pano"), panoramaOptions);
                GEvent.addListener(myPano, "error", handleNoFlash);
            });
        }
    });
}
0 голосов
/ 16 июля 2009

Поскольку функция обратного вызова, при которой вы вызываете внутреннее оповещение, запускается ПОСЛЕ вашего внешнего оповещения.

Попробуйте на секунду отложить внешнее оповещение, и вы увидите, что будет указано правильное значение

setTimeout(function(){ alert(newPoint); }, 1000);

Это происходит потому, что функция, в которой вы вызываете внутреннее оповещение, является асинхронной

РЕДАКТИРОВАТЬ: Обратите внимание, что вышеприведенное является плохой практикой и должно использоваться только для того, чтобы помочь вам понять, что происходит и почему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...