Неправильное значение родительских переменных JavaScript?

У меня такой код:

var address;
getAddress(0,0);
function getAddress(latlng) 
{
  if (latlng != null) 
  {
    geocoder.getLocations(latlng, 
    function(addresses) 
    {
      if (addresses.Status.code == 200) 
      { 
        address = addresses.Placemark[0].address.toString();
        alert(address);  // Outputs something :)
      }
    });
   }
   return address;   //returns nothing :(
}

Address всегда возвращает undefined, но предупреждение что-то выводит. Почему это?

(Геокодер является экземпляром API Карт Google)

Это кажется либо простым, либо сложным :(

Thomaschaaf 26.11.2008 18:59

Как определяется geocoder.getLocations? Не зная этого, очень сложно сказать, какие изменения вам нужно внести.

Illandril 26.11.2008 19:35

И не должен ли getAddress (0,0) иметь только один параметр? getAddress ([0,0])?

Victor 26.11.2008 19:48
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Принципы ООП в JavaScript
Принципы ООП в JavaScript
Парадигма объектно-ориентированного программирования имеет 4 основных принципа,
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Типы данных JavaScript
Типы данных JavaScript
В JavaScript существует несколько типов данных, включая примитивные типы данных и ссылочные типы данных. Вот краткое объяснение различных типов данных...
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик Модуль flexbox, также известный как гибкий модуль разметки box, помогает эффективно проектировать и...
2
3
5 571
4

Ответы 4

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

Это должно исправить любые проблемы с областью действия вашей функции:

var address = getAddress(0,0);

function getAddress(latlng) {
    if (latlng != null) {
        var address = geocoder.getLocations(latlng, function(addresses) {
            if (addresses.Status.code == 200) { 
                return addresses.Placemark[0].address.toString();
            }
        });
    }
return address;
}

Я не вижу причин, по которым это не сработает.

Чтобы быть вдвойне уверенным, что ничего не вернет, вызовите функцию следующим образом

window.alert(getAddress(0,0));

А затем посмотрите, что выводится

Если не ошибаюсь, похоже

geocoder.getLocations

Не вернет значение, но ожидает функцию обратного вызова, в вашем случае:

function(addresses) {
    if (addresses.Status.code == 200) { 
        return addresses.Placemark[0].address.toString();
    }
}

Этот «внутренний» возврат не имеет большого значения, поскольку он будет возвращаться внутрь geocoder.getLocations.

Итак, функция, выполняющая присваивание, вероятно, вызывается позже, чем внешний возврат (обратный вызов и статус 200 предполагают, что задействован медленный http-вызов).

То есть, если вы не можете изменить geocoder.getLocations, решение будет заключаться в том, чтобы сделать вашу функцию функциональной, например:

function getAddress(latlng, callback) {
    if (latlng != null) {
        geocoder.getLocations(latlng, function(addresses){
            if (addresses.Status.code == 200) { 
                address = addresses.Placemark[0].address.toString();
                alert(address);
                //Outputs something :)
                callback(address);
            }
        });
    }

}

И вы назовете это примерно так:

getAddress(ll, function(address){
   alert(address);
});

А в качестве бонуса можно избавиться от глобальной переменной :-)

Есть много материалов для чтения по функциональному javascript: google.com/search?q=functional+javascript

Victor 26.11.2008 19:47

Я успешно воспроизвел ошибку, реализовав асинхронную функцию geocoder.getLocations (). Если geocoder.getLocations () просто выполнит функцию параметра, то изменение переменной станет видимым до того, как getAddress () вернется, так что это не проблема области видимости.

var address;
alert("B: address returned: " + getAddress());
function getAddress() {
  executeFunction(function() {
    address = "myAddress";
    alert("C: address set to: " + address);
  });
  return address;
}

function executeFunction(aFunction) {
  alert("A: executing: " + aFunction);
  window.setTimeout(aFunction, 1);
}

Выполнение приведенного выше кода приводит к порядку предупреждений A-B-C, что означает, что адрес возвращается до его назначения. Замена window.setTimeout(aFunction, 1); на aFunction() приводит к порядку A-C-B, последним предупреждением является «B: возвращенный адрес: myAddress».

Другие вопросы по теме