Trying to return the latitude and longitude value from leaftlet geocoder

天大地大妈咪最大 提交于 2019-12-12 10:04:26

问题


I've been trying to figure out how I can fetch or return the value from geocoder block and use the value in another function. I keep getting an variable is not defined error

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:


As said in my comment, if you declare geocodeLocation globally and the function geocoder.geocode is asynchronous, then there’s no guarantee that the variable will be set when you’ll use it. The only way I can think of to solve this (that is, using geocodeLocation elsewhere) is using Promises. This way you can actually return geocodeLocation.

A quick explanation about how asynchronous execution works. (Don't worry I also used to ask how to return from an asynchronous call).

Say we have two functions

function1()
function2()

and function1() is asynchronous. What that means is that function2() won't wait that function1() ends to start running. But Geocoder.geocode's callback (the function you pass to it) will be called only when it finishes its asynchronous operation. But function2() will have already been called..

But there is way to return a value(using async/await), something along these lines:

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

Or, say your loc() function is asynchronous, then like so

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()

And finally, a quick explanation about async/await.

What does the await do?

It waits that the promise resolves before executing anything that comes after the await line. Without await, anything that comes after it will be executed before the promise resolves. You will get a promise in pending state.

Why must we use await in an async function?

The line with await might take 30 seconds to execute and your browser will freeze (that's also why ajax calls are asynchronous). The browser will ask you if you want to terminate that script that's freezing the browser (someone been doing something bad). So the async says the function is asynchronous, anything that comes after the function call won't wait that it finishes before starting. However, the await makes sure that anything that comes after it won't be executed before the promise resolves.



来源:https://stackoverflow.com/questions/58233338/trying-to-return-the-latitude-and-longitude-value-from-leaftlet-geocoder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!