如何使用 HTML5 GeoLocation API 的异步等待?

How to use Async Wait with HTML5 GeoLocation API?

第一种方法return承诺。

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

Returns reverseGeoCode 方法的结果。

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

使用自定义 class 进行 API 调用并 return 结果。

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

我是这样称呼的:

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

控制台记录未定义。

显示的片段有几个问题

  1. getAddress() 实际上 return 什么都没有。

  2. 如果使用await,则不需要then(),反之亦然(阻塞 或非阻塞,不能两者兼而有之)。

这是正确的版本

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

您还必须以类似的方式重写 reverseGeoCode,例如

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

下面的代码显示了类似的问题。尝试重构它。请记住在 async 函数中将其与 await 一起使用。类似于:

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



 

这是一个干净、简单的版本,将 API 封装到一个函数中:

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