Как установить переменную JavaScript изнутри функции? - PullRequest
0 голосов
/ 03 июня 2009

пожалуйста, посмотрите на следующий код. Когда значение i == 0, предупреждение 1 печатает значения переменных в соответствии с логикой. Но если я пытаюсь напечатать значения (предупреждение 2), он просто говорит «неопределенный, неопределенный». Мой вопрос заключается в том, какие изменения я должен сделать, чтобы значения, напечатанные во втором предупреждении (предупреждение 2), были такими же, как в предупреждении 1?

var testPoint = [];

function load() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById("map_canvas"));
    map.addControl(new GSmallMapControl());
    map.addControl(new GMapTypeControl());
    map.setCenter(new GLatLng(52.5271463402545, -1.50573921491311), 8, G_HYBRID_MAP);

    GDownloadUrl("controllers/gmap_genxml2.php", function(data) {
      var xml = GXml.parse(data);
      var markers = xml.documentElement.getElementsByTagName("marker");
      for (var i = 0; i < markers.length; i++) {
        if(i == 0) {
            testPoint["lat"] = parseFloat(markers[i].getAttribute("lat"));
            testPoint["lng"] = parseFloat(markers[i].getAttribute("lng"));

            /********* ALERT 1 ***********/
            alert(testPoint["lat"]+" "+testPoint["lng"]);
            /********* ALERT 1 End ***********/
        }
        var name = markers[i].getAttribute("name");
        var address = markers[i].getAttribute("address");
        var type = markers[i].getAttribute("type");
        var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
                                parseFloat(markers[i].getAttribute("lng")));
        var marker = createMarker(point, name, address, type);
        map.addOverlay(marker);
      }
    });

    /********* ALERT 2 ******************/
    alert(testPoint["lat"]+" "+testPoint["lng"]);
    /********* ALERT 2 Start ***********/
  }
}

Спасибо за вашу помощь. DeeJay

Ответы [ 4 ]

4 голосов
/ 03 июня 2009

Вы должны понимать, что большая часть JavaScript основана на событиях. Вот что происходит:

GDownloadUrl принимает обратный вызов. Второй аргумент - это функция, которая будет вызвана , когда запрос будет завершен . Он не будет вызываться сразу. Это важно. После закрытия вызова на GDownloadUrl Javascript продолжает работать. Он не ждет завершения запроса. На самом деле, если вы оставите оба оповещения внутри, вы увидите, что оповещение 2 сработает до оповещения 1. Таким образом, если вы хотите сделать определенную вещь с этими переменными после их выборки, вы должны переместить этот код в функцию и вызвать ее из обратного вызова GDownloadUrl. Именно так работает JavaScript, и вы к нему привыкнете.

1 голос
/ 03 июня 2009

Вы передаете указатель функции другому вызову функции. Это не обязательно заставляет код выполняться. Возможно, что время выключено. Ваш ALERT 1 происходит, когда вызывается функция (отлично), но ALERT 2 фактически выполняется до вызова функции!

Попробуйте ввести задержку в 1 секунду перед печатью содержимого testPoint.

1 голос
/ 03 июня 2009

Два ключа объекта lat и lng оцениваются только в функции обратного вызова, вызываемой GDownloadUrl.

Вам нужно подождать, пока он будет выполнен один раз, и тогда у вас будут правильные значения.

Я предлагаю вам переместить предупреждение 2 в конце этой функции обратного вызова.

0 голосов
/ 03 июня 2009
    testPoint = [];

    // This global var is introduced to mark that testPoint values are not yet loaded.
    var isLoaded = false;

    function load() {

    if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map_canvas"));
        map.addControl(new GSmallMapControl());
        map.addControl(new GMapTypeControl());
        map.setCenter(new GLatLng(52.5271463402545, -1.50573921491311), 8, G_HYBRID_MAP);

    GDownloadUrl("controllers/gmap_genxml2.php", function(data) {
      var xml = GXml.parse(data);
      var markers = xml.documentElement.getElementsByTagName("marker");
      for (var i = 0; i < markers.length; i++) {
        if(i == 0) {
                testPoint["lat"] = parseFloat(markers[i].getAttribute("lat"));
                testPoint["lng"] = parseFloat(markers[i].getAttribute("lng"));

                /********* ALERT 1 ***********/
                alert(testPoint["lat"]+" "+testPoint["lng"]);
                /********* ALERT 1 End ***********/

                // Set it to true to indicate that testPoint array is already loaded.
                isLoaded = true;
        }
        var name = markers[i].getAttribute("name");
        var address = markers[i].getAttribute("address");
        var type = markers[i].getAttribute("type");
        var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
                                parseFloat(markers[i].getAttribute("lng")));
        var marker = createMarker(point, name, address, type);
        map.addOverlay(marker);
      }
    });

    /********* ALERT 2 ******************/
     // Try to alert testPoint each 0.5 sec until we can successfully do it.
     function alert2() {
         // if testPoint is loaded - then alert it, if not then try in 0.5 sec.
         if (isLoaded) {
              alert(testPoint["lat"]+" "+testPoint["lng"])
         } else {
              setTimeout(alert2, 500);
         }
     };

     alert2();
    /********* ALERT 2 Start ***********/
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...