简体   繁体   中英

How to use Async Wait with HTML5 GeoLocation API?

The first method returns promise.

getCoordinates() {
  return new Promise(function(resolve, reject) {
    navigator.geolocation.getCurrentPosition(resolve, reject);
  });
}

Returns the result of reverseGeoCode method.

async getAddress() {
  await this.getCoordinates().then(position => {
    let latitude = position.coords.latitude;
    let longitude = position.coords.longitude;
    let url = Constants.OSMAP_URL + latitude + "&lon=" + longitude;
    // Reverse geocoding using OpenStreetMap
    return this.reverseGeoCode(url);
  });
}

Uses custom class to make an API call and return the result.

reverseGeoCode(url) {
  let requestService = new RequestService("json", url);
  requestService.call().then(result => {
    return result;
  });
}

This is how I call:

let geoLocation = new GeoLocation();
geoLocation.getAddress().then(r => {
  console.log(r);
});

The console logs undefined.

There are several problems with the shown snippets

  1. getAddress() doesn't actually return anything.

  2. If await is used, then() is not needed or vice-versa (blocking or non-blocking, not both).

Here is a correct version

async getAddress() {
  // notice, no then(), cause await would block and 
  // wait for the resolved result
  const position = await this.getCoordinates(); 
  let latitude = position.coords.latitude;
  let longitude = position.coords.longitude;
  let url = Constants.OSMAP_URL + latitude + "&lon=" + longitude;

  // Actually return a value
  return this.reverseGeoCode(url);  
}

You'll also have to rewrite reverseGeoCode in a similar fashion, something like

async reverseGeoCode(url) {
  let requestService = new RequestService("json", url);
  return await requestService.call();
}

The code below show similar issue. Try to refactor it. Remember to use it with await in async function. Something like:

window.onload = async () => {

const getCoords = async () => {
        const pos = await new Promise((resolve, reject) => {
          navigator.geolocation.getCurrentPosition(resolve, reject);
        });
    
        return {
          long: pos.coords.longitude,
          lat: pos.coords.latitude,
        };
    };

const coords = await getCoords();
}



 

Here is a clean, simple version that encapsulates the API into a single function:

<!doctype html>

<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Geolocation API</title>
  <meta name="description" content="demo of the geolocation api">
  <meta name="author" content="Mark Tyers">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script type="module" src="location.js" defer></script>
</head>

<body>
  <h1>GeoLocation</h1>
    <p></p>
    <p></p>
</body>
</html>

/* location.js */

try {
    const position = await getCurrentPosition()
    console.log(position)
    const lat = position.coords.latitude
    const lon = position.coords.longitude
    document.querySelector('p:nth-of-type(2)').innerText = `latitude: ${lat}`
    document.querySelector('p:nth-of-type(1)').innerText = `longitude: ${lon}`
} catch(err) {
    console.log(err)
    document.querySelector('p:nth-of-type(1)').innerText = err.message
}

function getCurrentPosition() {
    return new Promise( (resolve, reject) => {
        navigator.geolocation.getCurrentPosition(
            position => resolve(position),
            error => reject(error)
        )
    })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM