似乎我了解async / await的行为,但现在到现在,我深陷于自己的问题,无法解决它。 我正在尝试创建天气应用,因此我需要先请求纬度和经度,然后获取该信息以将请求发送到天气API并获取天气预报。正如Google文档
所述由于Google Maps API需要调用外部服务器,因此访问地理编码服务是异步的。
所以我正在尝试使用async / await来处理它。
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设置为form,用户将使用它来搜索城市,然后获取城市的天气预报。
这是我的搜索模型
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和几何经度未定义。
我该如何解决这个问题?
答案 0 :(得分:3)
codeAddress
不会await
进行任何操作,也不返回要await
处理的内容。即使geocode
尚未完成,它也会立即关闭。让它返回可以Promise
编辑的await
。
codeAddress() {
return new Promise((resolve, reject) => {
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');
resolve();
} else {
reject();
}
});
});
}
不幸的是,您将需要手动返回Promise
,因为Geocoder.geocode()
API仅遵循异步的回调样式,并且await
仅等待.then()
-ables(例如Promise
)。
答案 1 :(得分:0)
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();
}
});
});
}
当然还有其他方法可以将带有回调的函数转换为异步。