У меня такой код:
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)
Как определяется geocoder.getLocations? Не зная этого, очень сложно сказать, какие изменения вам нужно внести.
И не должен ли getAddress (0,0) иметь только один параметр? getAddress ([0,0])?
Я думаю, что все ваши проблемы связаны с размахом. Вообще говоря, вы не хотите полагаться на глобальное объявление переменной, которая будет использоваться в рамках функции.
Это должно исправить любые проблемы с областью действия вашей функции:
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
Я успешно воспроизвел ошибку, реализовав асинхронную функцию 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».
Это кажется либо простым, либо сложным :(