Возвращение значений в Javascript - PullRequest
0 голосов
/ 05 апреля 2011

У меня есть (надеюсь, довольно простая) проблема с Javascript.Я искал, но не нашел ничего, что действительно имеет отношение к проблеме.

В основном у меня есть функция (addToGlobe), которая при запуске вызывает две другие функции (codeAddressLat и codeAddressLng).Обе вызываемые функции должны возвращать значение с плавающей точкой первой функции, которая затем использует их.Подфункции определенно работают правильно - я сделал оператор print, чтобы проверить, что переменная «numfinal» в каждом имеет значение, и это так.

Однако, когда я добавляю операторы print в вызывающую функцию (как прокомментированокод), он возвращает «неопределенный».Таким образом, проблема, кажется, заключается в том, что возвращается значение numfinal.

Спасибо :))

function addToGlobe(uname, uid, pmcity) {
    // Get lat & long of city
    var pmlat = codeAddressLat(pmcity);
    var pmlong = codeAddressLng(pmcity);

    log(pmlat);   // PROBLEM! Prints 'undefined'
    log(pmlong);  // PROBLEM! Prints 'undefined'

    // Rest of function removed to keep it simple
}

function codeAddressLat(inputcity) {
    geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(-34.397, 150.644);

    geocoder.geocode( { 'address': inputcity}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
          var llsplit = new Array();

          bkresult = String(results[0].geometry.location);
          bkresult = bkresult.replace(/[\(\)]/g, "");
          llsplit = bkresult.split(',');

          numfinal = parseFloat(llsplit[0]);
          return numfinal;

      } else {
        log('<b><font color="#C40031">Geocode was not successful:</b> ' + status);
      }
    });
 }

  function codeAddressLng(inputcity) {
        // Basically the same function as above. Removed for simplicity
     }

Ответы [ 7 ]

1 голос
/ 05 апреля 2011

codeAddressLat фактически ничего не возвращает. Анонимная функция, которую она передает geocoder.geocode, является.

Поскольку geocoder.geocode работает асинхронно, codeAddressLat не может дождаться своего ответа. Таким образом, codeAddressLat действительно не может вернуть ничего ценного. Вместо этого codeAddressLat тоже должен стать асинхронным. Это общий шаблон в JavaScript.

function addToGlobe(uname, uid, pmcity) {
     codeAddressLat(pmcity, function(pmlat) {
        // do something with pmlat
    });

    ...
}

function codeAddressLat(inputcity, callback) {
    geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(-34.397, 150.644);

    geocoder.geocode( { 'address': inputcity}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
          var llsplit = new Array();

          bkresult = String(results[0].geometry.location);
          bkresult = bkresult.replace(/[\(\)]/g, "");
          llsplit = bkresult.split(',');

          numfinal = parseFloat(llsplit[0]);

          // instead of returning, call the callback with the result
          callback(numfinal);

      } else {
        log('<b><font color="#C40031">Geocode was not successful:</b> ' + status);
      }
    });
}
0 голосов
/ 05 апреля 2011

Эта функция geocoder.geocode выглядит как асинхронная.Ваши функции codeAddressLat и codeAddressLng возвращают void до того, как функция geocoder.geocode вернула данные с сервера.

Чтобы обойти это, нужно вложить ваши вызовы в geocoder.geocode и использовать переменную область видимости.так что после того, как все вызовы AJAX вернутся, вы можете вызвать вашу функцию addToGlobe, передавая два нужных вам параметра.

Примерно так:

codeAddressLatAndLong(pmcity);

function addToGlobe(pmlatlat, pmlatlong) {
    log(pmlat);   // PROBLEM! Prints 'undefined'
    log(pmlong);  // PROBLEM! Prints 'undefined'

    // Rest of function removed to keep it simple
}

function codeAddressLatAndLong(inputcity) {
    // stuff

    geocoder.geocode( { 'address': inputcity}, function(results, status) {
      // stuff goes here
      pmlat = parseFloat(llsplit[0]);
      geocoder.geocode({...}, function(results, status) {
         // more stuff
         pmlatlong = something;
         addToGlobe(pmlatlat, pmlatlong);
      });
    });
}

Добро пожаловать в мир AJAX.

0 голосов
/ 05 апреля 2011

Это работает?

function codeAddressLat(inputcity) {
    geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(-34.397, 150.644);

    return geocoder.geocode( { 'address': inputcity}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
          var llsplit = new Array();

          bkresult = String(results[0].geometry.location);
          bkresult = bkresult.replace(/[\(\)]/g, "");
          llsplit = bkresult.split(',');

          numfinal = parseFloat(llsplit[0]);
          return numfinal;

      } else {
        log('<b><font color="#C40031">Geocode was not successful:</b> ' + status);
      }
    });
 }
0 голосов
/ 05 апреля 2011

Запрос геокода в вызове метода codeAddressLat не возвращает значение вызывающей стороне.Ваше возвращение имеет другую сферу.

0 голосов
/ 05 апреля 2011

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

0 голосов
/ 05 апреля 2011

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

0 голосов
/ 05 апреля 2011

У вас нет оператора возврата в codeAddressLat, у вас есть один внутри функции обратного вызова, определенной внутри codeAddressLat.

...