Попытка вернуть значение широты и долготы из геокодера листовки - PullRequest
2 голосов
/ 04 октября 2019

Я пытался выяснить, как я могу получить или вернуть значение из блока geocoder и использовать значение в другом function. Я получаю ошибку variable is not defined

geocoder = new L.Control.Geocoder.Nominatim();
var location = $('.location').text();

geocoder.geocode(location, function(results) {    
        var latLng = new L.LatLng(results[0].center.lat, results[0].center.lng);
        var marker = new L.Marker (latLng);
        // console.log(Object.values(latLng));   

        var geocodeLocation = Object.values(latLng);
});
    
function loc() {

      console.log(geocodeLocation);
      
}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"
    integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
    crossorigin=""></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/perliedman-leaflet-control-geocoder/1.9.0/Control.Geocoder.js"></script>
    
    
      <span class="location">Philippines</span>

1 Ответ

3 голосов
/ 06 октября 2019

Как сказано в моем комментарии, если вы объявляете geocodeLocation глобально и функция geocoder.geocode является асинхронной, то нет никакой гарантии, что переменная будет установлена ​​при ее использовании. Единственный способ решить эту проблему (то есть с помощью geocodeLocation в другом месте) - это использовать Promises. Таким образом, вы можете вернуть geocodeLocation.

Краткое объяснение того, как работает асинхронное выполнение. (Не волнуйтесь, я также спрашивал, как вернуться из асинхронного вызова).

Скажем, у нас есть две функции

function1()
function2()

и function1() асинхронный. Это означает, что function2() не будет ждать окончания работы function1(). Но обратный вызов Geocoder.geocode (функция, которую вы ему передаете) будет вызываться только после завершения асинхронной операции. Но function2() уже будет вызван ..

Но есть способ вернуть значение (используя async / await), что-то вроде этого:

function geocode(location, func) { //that's the geocoder.geocode
  //calculate coordinates with location
  var results = { coordinates: { lat: '37.423021', long: '-122.083739' } }
  func(results);
}
    
async function fetchGeocodeLocation(location) {

  var promise = new Promise((resolve, reject) => { //wrap your geocoder.geocode function in a Promise
    geocode(location, function(results) { 
      //var latLng = new L.LatLng(results[0].center.lat, results[0].center.lng);
    //var marker = new L.Marker (latLng);
    // console.log(Object.values(latLng));   

    //var geocodeLocation = Object.values(latLng);  

      resolve(results.coordinates);
    });
  });

  var geoCodeLocation = await promise;
  return geoCodeLocation;
}

fetchGeocodeLocation("somewhere").then(geoCodeLocation => console.log("geoCodeLocation", geoCodeLocation))

Или, скажем, ваша функция loc () асинхронная, а затем вот так

function geocode(location, func) {
  //calculate coordinates with location
  var results = { coordinates: { lat: '37.423021', long: '-122.083739' } }
  func(results);
}
    
function fetchGeocodeLocation(location) {

  return new Promise((resolve, reject) => { //wrap your geocoder.geocode function in a Promise
    geocode(location, function(results) { 
      //var latLng = new L.LatLng(results[0].center.lat, results[0].center.lng);
    //var marker = new L.Marker (latLng);
    // console.log(Object.values(latLng));   

    //var geocodeLocation = Object.values(latLng);  

      resolve(results.coordinates);
    });
  });
}

async function loc() {
  var location = "somewhere";
  var geoCodeLocation = await fetchGeocodeLocation(location);
  console.log("geoCodeLocation", geoCodeLocation)
}

loc()

И, наконец, краткое объяснение асинхронное / ожидание .

Что делает ожидание?

Он ожидает разрешения обещания, прежде чем выполнить что-либо после строки ожидания. Без ожидания все, что придет после этого, будет выполнено до того, как обещание разрешится. Вы получите обещание в состоянии ожидания.

Почему мы должны использовать await в асинхронной функции?

Выполнение строки с await может занять 30 секунд, а ваш браузербудет зависать (именно поэтому вызовы ajax являются асинхронными). Браузер спросит вас, хотите ли вы закрыть тот скрипт, который зависает в браузере (кто-то делал что-то плохое). Таким образом, async говорит, что функция асинхронная, все, что приходит после вызова функции, не будет ждать, пока не завершится, прежде чем начать. Однако ожидание гарантирует, что все, что придет после этого, не будет выполнено до разрешения обещания.

...