JS中如何让async异步函数在另一个异步函数执行完成后运行?
问题核心原因
你的基础逻辑方向是对的,出现异常的核心是几个细节错误导致定位逻辑提前抛出错误,终止了正常执行流程:
AJAX函数加了export关键字,若你未将脚本声明为ES模块,会直接抛出语法错误进入catch块- API请求URL中使用了HTML转义字符
&而非原生&,导致请求参数识别失败 - 未在定位失败的分支中处理天气请求逻辑
修复方案
1. 完整可运行代码
const WEATHER_API_KEY = "f19d6e315954bfb123e794ab55aa28c4"; const state = { location: { // 巴黎默认坐标 lat: 48.8566969, lng: 2.3514616 } }; // 定位配置项 const options = { enableHighAccuracy: true, timeout: 5000, maximumAge: 0 }; // 封装定位Promise const getPosition = function () { return new Promise(function (resolve, reject) { navigator.geolocation.getCurrentPosition(resolve, reject, options); }); }; // 请求超时工具函数 const TIMEOUT_SEC = 5; const timeout = function (s) { return new Promise(function (_, reject) { setTimeout(function () { reject(new Error(`请求超时,超过${s}秒`)); }, s * 1000); }); }; // AJAX请求工具,移除冗余的export和method判断逻辑 const AJAX = async function (url) { try { const fetchPro = 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; } }; // 统一封装天气请求逻辑,复用代码 const fetchWeather = async () => { // 替换URL中的转义字符&为原生& 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); // 此处补充UI更新逻辑 } const loadData = async function () { try { // 等待用户授权和定位结果 const { coords } = await getPosition(); const { latitude, longitude } = coords; state.location.lat = latitude; state.location.lng = longitude; console.log('定位成功,使用用户当前坐标'); } catch (err) { // 定位失败(用户拒绝、超时、浏览器不支持)时使用默认坐标 console.error('定位失败,使用默认巴黎坐标:', err.message); } finally { // 无论定位成功失败,统一触发天气请求 await fetchWeather(); } }; window.addEventListener("load", loadData);
2. 疑问解答
- 关于异步执行顺序:
async/await串行调用是严格按代码顺序执行的,只要前一个await没有抛出错误,一定会等待执行完成再运行下一行代码,不存在顺序错乱的问题。你遇到的未等授权就发请求的现象,本质是定位逻辑提前报错跳出了try块。 - 关于定位失败的处理:可以在catch块中直接调用天气API,使用
finally块统一执行请求逻辑更简洁,避免重复代码。 - 关于返回值获取:修复语法错误后,
await getPosition()会正常返回定位结果,你可以正常拿到经纬度赋值到state中。
内容的提问来源于stack exchange,提问作者halbmond
相关产品推荐
相关产品推荐

