Возврат значения из функции обратного вызова Google Maps

#javascript #google-maps #asynchronous

#javascript #google-карты #асинхронный

Вопрос:

Привет, я работаю с Google Maps API, у меня есть этот огромный код, поэтому я не хочу отпугивать людей кодом, в основном это то, что мне нужно сделать

У меня есть функция javascript (1), которую я вызываю из Html после того, как кто-то нажимает кнопку, из этой функции я выполняю некоторую обработку для вычисления широт и долгот и вызываю пользовательскую функцию, которая использует широты и долготы и вызывает функцию Google maps. Мне нужно передать это значение из функции обратного вызова карт Google обратно в функцию javascript (1)

вот как это происходит

—————Файл First.html—————-

 <script type="text/javascript" src="functions.js"></script>
<script type="text/javascript">
function docalculation
{
  .....some calculations for latlng......
  var value = get_value(latlng);
}
</script>
<html>
  .....html file....
  <input type="button" value="Create Directions" onClick="docalculation()">
</html>
  

——————-файл functions.js—————-

 var return_val;
function get_val(latlng)
{
  geocoder = new google.maps.Geocoder();
  geocoder.geocode({'latLng': latlng}, function(results, status) {

  return_val = (results[0].address_components[i].long_name);
  alert(return_val); //here I get the value that I need in alert
  }

alert (return_val); // here the value suddenly becomes undefined
return val; // hence returns undefined
}
  

Пожалуйста, помогите, я застрял здесь и не смог найти решение даже после 2 дней поиска в Google и перепробования всего, что я знаю.

любая помощь приветствуется, спасибо

Самым простым решением, которое я ищу, было бы каким-либо способом сохранить значение return_val в значение переменной

Спасибо

Комментарии:

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

2. Есть ли какой-либо способ сохранить это значение (return_val)….. Мне отчаянно нужно решение

Ответ №1:

Это потому, что geocode() является асинхронным: он возвращает немедленно, но функция обратного вызова вызывается, как только поступает ответ. Вам нужно принять обратный вызов в get_val() и передать значение этому методу вместо того, чтобы пытаться вернуть его (это невозможно):

 function get_val(latlng, cb) {
    geocoder = new google.maps.Geocoder();
    geocoder.geocode({
        'latLng': latlng
    }, function (results, status) {
        cb(results[0].address_components[i].long_name);
    });
}
  

Использование:

 get_value(latlng, function(longName) {
    /* do something */
});
  

Комментарии:

1. Бьюсь об заклад, вопросы о возвращаемом значении и асинхронных функциях являются одними из наиболее распространенных вопросов JavaScript здесь

2. Спасибо за ответ, но есть еще одна проблема, с которой я столкнулся бы, используя это решение ……. то, что функция возвращает, это название дороги …… что мне нужно сделать, это сохранить первое значение в переменной, скажем, first road, и сохранить второе значение в переменной, скажем, second road, и сравнить переменные first road и second road, чтобы увидеть, имеют ли они одинаковое значение, и мне нужно сделать это в цикле несколько раз …. хотя спасибо за быстрый ответ…

3. @ThiefMaster, ваше использование должно быть get_value( latlng, function(longName) { /*do something*/}

4. @ThiefMaster не могли бы вы предложить что-нибудь еще, пожалуйста

5. @Nick: Вы можете передать несколько аргументов функции обратного вызова

Ответ №2:

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

 /**
 * @param {string[]} values longitude strings
 * @param cb {function} The callback that will be passed a 
 *        map keyed by latlng strings where each value
 *        is the long name of the street
 */
function getLongNames(values, cb) {
    var returnValues = {};
    var responseCount = 0;
    var geocoder = new google.maps.Geocoder();

    for (var i =0; i < values.length; i  ) {
        getSingleName(values[i], function(latLng, longName) {
            returnValues[latLng] = longName;
            responseCount  ;
            if (responseCount == values.length) {
                cb(returnValues);
            }
        });
    }

    function getSingleName(latlng, cb) {
        geocoder.geocode({
            'latLng': latlng
        }, function (results, status) {
            cb(latlng, results[0].address_components[i].long_name);
        });
    }
}
  

И вы называете это так

 // The callback is the code that is run once all the latLng have been processed
getLongNames(["latLng1", "latLng2","latLng2"], function (valueMap) {
  for (var latLng in valueMap) {
    console.log("Latitude Longitude:"   latLng   " Long Name "   valueMap[latLng]);
  }
});
  

Комментарии:

1. ПРИВЕТ, Хуан, спасибо за ответ …. ваш код помогает таким образом, что я могу сравнить обе дороги в функции, но после сравнения их мне также нужно передать логическое значение, чтобы определить, совпадают значения или нет, и я не думаю, что мы сможем достичь этого после использования этого кода……….

2. @Nick: Я не понимаю, что вы имеете в виду. У вас есть все значения на возвращаемой карте. Что это такое, с чем вы не можете сравнить? Покажите свой код и то, что вы на самом деле пытаетесь сделать.

3. @Juam Mendes: По моему мнению, самое простое решение, которое я ищу для этой проблемы, — это какой-то способ извлечь значение переменной return_val, которое я упомянул в исходном коде, и сохранить его в некоторой переменной в функции docalculation (в исходном вопросе) …… могу ли я в любом случае этого добиться…… Я действительно ценю ваши усилия …. пожалуйста, помогите мне с этой злобной проблемой, если можете, спасибо

4. @Nick: По вашему мнению, вы ошибаетесь 🙂 Нет способа вызвать функцию и заставить ее вернуть значение, такова природа асинхронных вызовов. Возвращаемые значения передаются через функцию обратного вызова. Вам нужно скорректировать свой код и подумать об использовании обратных вызовов. Мы дали вам много подсказок о том, как это сделать.

5. @Juan Mendes I это означает, что я должен отказаться от всего моего проекта …. если я не могу этого достичь ….. потому что природа проблемы, над которой я работаю, требует, чтобы я сохранил значение….