如何使用 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);
});
控制台记录未定义。
显示的片段有几个问题
getAddress()
实际上 return
什么都没有。
如果使用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)
)
})
}
第一种方法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);
});
控制台记录未定义。
显示的片段有几个问题
getAddress()
实际上return
什么都没有。如果使用
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)
)
})
}