[英]Using async/await to get data from a callback and return a value only after a promise is resolved
I'm trying to use async/await but I think I'm misunderstanding something critically. 我正在尝试使用async / await,但我认为我对某些事情有误解。
As basically as possible, I am trying to calculate the distance between a list of locations and one designated location using google maps api. 基本上,我正在尝试使用Google Maps API计算位置列表和一个指定位置之间的距离。
Here is a rough example of what I'm trying to do: https://jsfiddle.net/qu5y69rj/1/ 这是我要执行的操作的粗略示例: https : //jsfiddle.net/qu5y69rj/1/
You can see that the result of that function is undefined
3 times instead of what I would expect which would be {distance: "ZERO_RESULTS"}
for each call in the case of my contrived example. 您可以看到该函数的结果
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;
}
Why is result being returned before the promise is resolved? 为什么在解决诺言之前返回结果? How can I return the value of
result
only after that promise is resolved? 只有兑现了承诺,我如何才能返回
result
的值? It is my understanding that by telling javascript to await, I'm saying don't move forward until this promise has resolved. 据我了解,通过告诉javascript等待,我是说直到这个诺言得以解决之前,不要前进。 Is that incorrect?
那不对吗? I'm pretty confused and this has me pulling my hair out.
我很困惑,这让我拔头发。 Any help is appreciated.
任何帮助表示赞赏。
The service.getDistanceMatrix
accepts a callback which means ti most likely doesn't return a promise. service.getDistanceMatrix
接受回调,这意味着ti最有可能不返回承诺。
However, async functions expect promises. 但是,异步功能会带来希望。
As a fix, you can wrap getDistanceMatrix
it in a promise (or use another method that does return a promise): 作为解决方法,您可以将
getDistanceMatrix
包裹在一个getDistanceMatrix
中(或使用另一个返回getDistanceMatrix
方法):
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
};
};
There are three ways to do async operations with JavaScript: 使用JavaScript进行异步操作的方法有以下三种:
undefined
), and when the async operation completes, the callback is called. undefined
),并且在异步操作完成时,将调用回调。 async
keyword to get the values of async operations inside its definition. async
关键字在其定义内获取异步操作的值。 Whatever is returned using the return
keyword will be wrapped in a promise. return
关键字返回的任何内容都将包装在promise中。 Since getDistanceMatrix
accepts a callback, it returns nothing. 由于
getDistanceMatrix
接受回调,因此不返回任何内容。 The await
keyword as used in the code doesn't need to wait; 代码中使用的
await
关键字不需要等待; it immediately gets the undefined
value returned by getDistanceMatrix
. 它立即获得
getDistanceMatrix
返回的undefined
值。 When the operation completes and the callback is called, the getDistance
has long finished executing and returned. 当操作完成并调用回调时,
getDistance
早已完成执行并返回。
You need to wrap getDistanceMatrix
so it returns a promise, make getAllDistance()
return a promise as well, and await that promise in your console.log()
statement: 您需要包装
getDistanceMatrix
以便它返回一个promise,使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); });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.