Javascript 如何执行相互依赖的多个异步函数?
我似乎理解async/await的行为,但现在我被我的问题深深地困扰着,无法解决它。 我正在尝试创建天气应用程序,因此我需要首先请求纬度和经度,然后获取该信息,以向天气API发送请求并获取天气预报。正如谷歌文档中所说的那样 访问地理编码服务是异步的,因为Google Maps API需要调用外部服务器 所以我尝试使用async/await来处理它Javascript 如何执行相互依赖的多个异步函数?,javascript,async-await,geocoding,ecmascript-2017,Javascript,Async Await,Geocoding,Ecmascript 2017,我似乎理解async/await的行为,但现在我被我的问题深深地困扰着,无法解决它。 我正在尝试创建天气应用程序,因此我需要首先请求纬度和经度,然后获取该信息,以向天气API发送请求并获取天气预报。正如谷歌文档中所说的那样 访问地理编码服务是异步的,因为Google Maps API需要调用外部服务器 所以我尝试使用async/await来处理它 import Search from './models/Search'; import * as searchView from './views/
import Search from './models/Search';
import * as searchView from './views/searchView';
import { elements } from './views/base';
/*
* Search controller
*/
const state = {
};
const controlSearch = async () => {
const query = searchView.getInput();
if (query) {
state.forecast = new Search(query);
try {
await state.forecast.codeAddress();
await state.forecast.getForecast(state.forecast);
console.log(state);
} catch (error) {
console.log(error);
}
}
};
elements.searchForm.addEventListener('submit', (e) => {
e.preventDefault();
controlSearch();
});
这是我的控制器。在底部,我将eventListener放入表单中,用户将使用它搜索城市,然后获取预测
这是我的搜索模型
import { key, proxy } from '../config';
export default class Search {
constructor(query) {
this.query = query;
}
codeAddress() {
const geocoder = new google.maps.Geocoder();
geocoder.geocode({ address: this.query }, (results, status) => {
if (status === 'OK') {
this.latitude = results[0].geometry.location.lat();
this.longitude = results[0].geometry.location.lng();
console.log(this.latitude, this.longitude, 'lat long');
}
});
}
async getForecast(geometry) {
console.log(geometry, 'geometry');
const result = await fetch(`${proxy}https://api.darksky.net/forecast/${key}/${geometry.latitude},${geometry.longitude}`);
const forecast = await result.json();
forecast.then((res) => {
this.forecast = res;
});
}
}
问题在于,当请求darkSky API时,geometry.latitude和geometry longitude未定义
我如何处理这个问题
codemaddress
不会wait
任何内容或返回要wait
ed的内容。即使geocode
尚未完成,它也会立即关闭。让它返回一个可以等待的承诺
codemaddress(){
返回新承诺((解决、拒绝)=>{
const geocoder=新的google.maps.geocoder();
地理编码({
地址:this.query
},(结果、状态)=>{
如果(状态=='OK'){
this.latitude=results[0].geometry.location.lat();
this.longitude=results[0].geometry.location.lng();
log(this.latitude,this.longitude,'lat-long');
解决();
}否则{
拒绝();
}
});
});
}
代码地址
不会等待任何内容或返回要等待的内容。即使地理编码
尚未完成,它也会立即关闭。让它返回一个可以等待的承诺
codemaddress(){
返回新承诺((解决、拒绝)=>{
const geocoder=新的google.maps.geocoder();
地理编码({
地址:this.query
},(结果、状态)=>{
如果(状态=='OK'){
this.latitude=results[0].geometry.location.lat();
this.longitude=results[0].geometry.location.lng();
log(this.latitude,this.longitude,'lat-long');
解决();
}否则{
拒绝();
}
});
});
}
codemaddress
是异步的(因为响应是在回调中处理的),但您没有将其视为异步的。试试这个:
async codeAddress() {
const geocoder = new google.maps.Geocoder();
return new Promise((resolve, reject) => {
geocoder.geocode({ address: this.query }, (results, status) => {
if (status === 'OK') {
this.latitude = results[0].geometry.location.lat();
this.longitude = results[0].geometry.location.lng();
console.log(this.latitude, this.longitude, 'lat long');
resolve();
} else {
reject();
}
});
});
}
当然还有其他方法可以将带有回调的函数转换为异步函数。
codeAddress
是异步的(因为响应是在回调中处理的),但不能将其视为异步的。试试这个:
async codeAddress() {
const geocoder = new google.maps.Geocoder();
return new Promise((resolve, reject) => {
geocoder.geocode({ address: this.query }, (results, status) => {
if (status === 'OK') {
this.latitude = results[0].geometry.location.lat();
this.longitude = results[0].geometry.location.lng();
console.log(this.latitude, this.longitude, 'lat long');
resolve();
} else {
reject();
}
});
});
}
当然还有其他方法可以将带有回调的函数转换为异步函数。
codemaddress
不会等待任何东西或返回要等待的东西。即使geocode
尚未完成,它也会立即关闭。@zero298那么你的意思是让codemaddress异步/等待?codemaddress
不wait
任何内容或返回要wait
ed的内容。即使geocode
尚未完成,它也会立即关闭。@zero298所以你的意思是使codeAddress异步/wait?是的,这对我来说很有效。非常感谢。有没有办法不用承诺就解决它?@NorayrGhukasyan请看我的编辑<考虑到geocode
的API,code>Promise可能是最干净的方法。是的,这对我很有用。非常感谢。有没有办法不用承诺就解决它?@NorayrGhukasyan请看我的编辑<鉴于geocode
的API,code>Promise可能是实现这一点最干净的方法。如果没有async
为什么要等待-等待任何事情?如果没有为什么要等待async
-等待任何事情?