我正在尝试使用 vanilla JS 和 API 创建一个天气报告应用程序。我的目标是:
- 当网页完成加载时,我想询问用户他们的位置。
- 如果用户接受请求 我想使用浏览器 api 获取他们的坐标并存储纬度和经度,然后运行另一个异步函数,该函数将使用这些纬度和经度数据从 OpenWeather api 获取数据。湾。相应地更新 UI。
- 如果用户阻止请求:我仍想从 OpenWeather api 获取数据,但这次使用默认的纬度和经度值(例如巴黎)
我面临的问题是:
- 我正在尝试使用承诺功能获取地理位置。因此,如果使用 async/await,这将在异步函数中执行,但我无法一个接一个地运行两个异步函数,以便它可以使用先前执行的函数的响应数据。
- 如果用户在浏览器中阻止该位置,该函数将被拒绝并执行catch块,那么我应该将天气api函数放在catch块中以使用默认的经纬度值还是做其他事情?
- 据我所知,连续执行多个异步函数并不能保证结果将以相同的顺序出现,因此有时天气 api 函数会使用默认的 lat 和 lon 值成功地从 api 获取数据,而不是等待用户的位置。如何修复代码以便获得所需的输出?
我是 JS 和 SO 的新手,所以如果需要任何澄清,请告诉我。顺便说一句,我还分享了代码以便更好地理解。抱歉发了这么长的帖子:(
const WEATHER_API_KEY = "f19d6e315954bfb123e794ab55aa28c4";
const state = {
location: {
//setting default location of paris
lat: 48.8566969,
lng: 2.3514616
}
};
///////////////////////////////////////
// Geolocation api function
const options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
// Getting location using geolocation API
const getPosition = function () {
return new Promise(function (resolve, reject) {
navigator.geolocation.getCurrentPosition(resolve, reject, options);
});
};
//////////////////////////////////////////////
// Helper function to fetch data from api
const TIMEOUT_SEC = 5;
const timeout = function (s) {
return new Promise(function (_, reject) {
setTimeout(function () {
reject(new Error(`Request took too long! Timeout after ${s} second`));
}, s * 1000);
});
};
//get json data from api
export const AJAX = async function (url, method = undefined) {
try {
const fetchPro = method
? fetch(url, {
method: "get"
})
: fetch(url);
const res = await Promise.race([fetchPro, timeout(TIMEOUT_SEC)]);
const data = await res.json();
if (!res.ok) throw new Error(`${data.message} (${res.status})`);
return data;
} catch (err) {
throw err;
}
};
//////////////////////////////
// Executing functions and fetching data
const loadData = async function () {
try {
const { coords } = await getPosition();
const { latitude, longitude } = coords;
state.location.lat = latitude;
state.location.lng = longitude;
const weatherData = await AJAX(
`https://api.openweathermap.org/data/2.5/onecall?lat=${state.location.lat}&lon=${state.location.lng}&&units=metric&appid=${WEATHER_API_KEY}`
);
console.log(weatherData);
} catch (err) {
console.error("Error occured!!", err);
}
};
window.addEventListener("load", loadData);