我正在尝试使用async / await,但我认为我批判性地误解了一些东西。
尽可能基本上,我正在尝试使用google maps api计算位置列表与指定位置之间的距离。
以下是我正在尝试做的一个粗略示例:https://jsfiddle.net/qu5y69rj/1/
你可以看到该函数的结果是undefined
3次,而不是我所期望的,对于我设想的例子,每次调用都是{distance: "ZERO_RESULTS"}
。
getDistance = async (start, end) => {
const origin = new google.maps.LatLng(start[0], start[1]);
const final = new google.maps.LatLng(end[0], end[1]);
const service = new google.maps.DistanceMatrixService();
let result; //need to return this value!
await service.getDistanceMatrix(
{
origins: [origin],
destinations: [final],
travelMode: 'DRIVING'
}, (response, status) => {
if(status === 'OK') result = {distance: response.rows[0].elements[0].status}
}
)
return result;
}
为什么在承诺解决之前返回结果?只有在该承诺解决后,我才能返回result
的值?我的理解是,通过告诉javascript等待,我说在这个承诺解决之前不要继续前进。这是不正确的?我很困惑,这让我把头发拉了出来。任何帮助表示赞赏。
答案 0 :(得分:7)
service.getDistanceMatrix
接受回调,这意味着很可能不会返回承诺。
但是,异步函数需要承诺。
作为修复,您可以将getDistanceMatrix
包装在一个promise中(或者使用另一个返回promise的方法):
const getDistanceMatrix = (service, data) => new Promise((resolve, reject) => {
service.getDistanceMatrix(data, (response, status) => {
if(status === 'OK') {
resolve(response)
} else {
reject(response);
}
})
});
getDistance = async (start, end) => {
const origin = new google.maps.LatLng(start[0], start[1]);
const final = new google.maps.LatLng(end[0], end[1]);
const service = new google.maps.DistanceMatrixService();
const result = await getDistanceMatrix(
service,
{
origins: [origin],
destinations: [final],
travelMode: 'DRIVING'
}
)
return {
distance: result.rows[0].elements[0].status
};
};
答案 1 :(得分:4)
使用JavaScript进行异步操作有三种方法:
undefined
),当异步操作完成时,将调用回调函数。async
关键字在其定义中获取异步操作的值。使用return
关键字返回的内容将包含在一个承诺中。由于getDistanceMatrix
接受回调,因此不返回任何内容。代码中使用的await
关键字不需要等待;它立即获得undefined
返回的getDistanceMatrix
值。当操作完成并且调用回调时,getDistance
已经完成执行并返回。
您需要包装getDistanceMatrix
以便它返回一个promise,make getAllDistance()
也会返回一个promise,并在console.log()
语句中等待该promise:
const coords = [
['-36.22967', '-125.80271'],
['54.06395', '54.06395'],
['-5.00263', '-137.92806']
];
function getDistance (start, end) {
const origin = new google.maps.LatLng(start[0], start[1]);
const final = new google.maps.LatLng(end[0], end[1]);
const service = new google.maps.DistanceMatrixService();
return new Promise((resolve, reject) => {
service.getDistanceMatrix(
{
origins: [origin],
destinations: [final],
travelMode: 'DRIVING'
}, (response, status) => {
if(status === 'OK') {
resolve({ distance: response.rows[0].elements[0].status });
} else {
reject(new Error('Not OK'));
}
}
);
});
}
function getAllDistance (starts, end) {
const promisedDistances = starts.map((start) => getDistance(start, end));
// Promise.all turns an array of promises into a promise
// that resolves to an array.
return Promise.all(promisedDistances);
}
getAllDistance(coords, ['-30.23978', '-161.31203'])
.then(result => { console.log(result); });