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

77
7

У меня есть следующий код:


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, но предупреждение выводит что-то. Почему это?


(Geocoder - это экземпляр API Карт Google)

спросил(а) 2021-01-25T10:36:04+03:00 6 месяцев назад
1
Решение
90

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


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

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;
}

ответил(а) 2021-01-25T10:36:04+03:00 6 месяцев назад
45

Если я не ошибаюсь, это выглядит как


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

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

ответил(а) 2021-01-25T10:36:04+03:00 6 месяцев назад
46

Я успешно воспроизвел ошибку, выполнив геокодер .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".

ответил(а) 2021-01-25T10:36:04+03:00 6 месяцев назад
-9

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


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


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

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

ответил(а) 2021-01-25T10:36:04+03:00 6 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема