React中Axios连续两次GET请求异常:经纬度为空及返回undefined
解决OpenWeatherMap API调用中的异步问题
问题背景
我正在使用OpenWeatherMap API获取赫尔辛基等城市的当前天气。最初编写的代码如下:
import axios from 'axios' const apiKey = import.meta.env.VITE_OWM_API_KEY const getCityCoordinatesApiUrl = (city) => { return `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}` } const getCityWeatherApiUrl = (longitude, latitude) => { return `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&appid=${apiKey}` } const getCityWeather = (city, weatherJsonContainer) => { const url = getCityCoordinatesApiUrl(city) let longitude = null let latitude = null axios.get(url).then(response => { console.log("Hell", response.data) longitude = response.data.coord.lon latitude = response.data.coord.lat }) .catch(error => { console.log("Error in getCityWeather:", error) alert(`Could not obtain weather of ${city}!`) }) console.log("getCityWeather: received:", latitude, longitude) const url2 = getCityWeatherApiUrl(longitude, latitude) const outData = axios.get(url2).then(response => response.data) console.log("getCityWeather: outData:", outData) }
初始问题:longitude和latitude始终为null
这是因为axios.get是异步操作,代码执行到打印经纬度和发起第二个请求时,第一个API请求还未完成,因此longitude和latitude仍保持初始的null值。
修改后的代码及新问题
参考相关代码调整后,代码更新为:
import axios from 'axios' const apiKey = import.meta.env.VITE_OWM_API_KEY const getCityCoordinatesApiUrl = (city) => { return `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}` } const getCityWeatherApiUrl = (longitude, latitude) => { return `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&appid=${apiKey}` } const getCityWeather = (city) => { const url = getCityCoordinatesApiUrl(city) axios.get(url).then(response => { const longitude = response.data.coord.lon const latitude = response.data.coord.lat const url2 = getCityWeatherApiUrl(longitude, latitude) return axios.get(url2); }) .then(response => { console.log(response.data) return response.data }) .catch(error => { console.log("Error in getCityWeather:", error) alert(`Could not obtain weather of ${city}!`) }) } export default { getCityWeather }
调用代码为:
const weatherJsonData = weatherService.getCityWeather('Helsinki')
新问题:第二个then中的return response.data返回undefined
核心原因是getCityWeather函数没有返回Promise链,调用时直接赋值的weatherJsonData只能拿到函数默认返回的undefined,无法获取异步请求的结果。
解决方法
1. 让getCityWeather返回Promise链
修改函数,返回整个axios请求的Promise链,这样调用方就能通过Promise获取异步结果:
const getCityWeather = (city) => { const url = getCityCoordinatesApiUrl(city) // 返回Promise链,让调用方可以获取异步结果 return axios.get(url).then(response => { const longitude = response.data.coord.lon const latitude = response.data.coord.lat const url2 = getCityWeatherApiUrl(longitude, latitude) return axios.get(url2); }) .then(response => { console.log(response.data) return response.data }) .catch(error => { console.log("Error in getCityWeather:", error) alert(`Could not obtain weather of ${city}!`) // 抛出错误,让调用方可以捕获并处理 throw error; }) }
2. 正确调用异步函数
因为getCityWeather现在返回的是Promise,所以需要用以下两种方式之一获取结果:
方式一:使用.then()链式调用
weatherService.getCityWeather('Helsinki') .then(weatherJsonData => { console.log(weatherJsonData); // 在这里处理获取到的天气数据 }) .catch(error => { // 处理请求失败的情况 });
方式二:使用async/await(代码更简洁易读)
注意await必须在async函数内部使用:
async function fetchCityWeather() { try { const weatherJsonData = await weatherService.getCityWeather('Helsinki'); console.log(weatherJsonData); // 处理天气数据 } catch (error) { // 处理异常 } } // 调用函数 fetchCityWeather();
关键说明
- 异步操作无法直接同步赋值结果,必须通过Promise的
.then()或await来获取异步返回值。 - 在
catch中抛出错误可以让调用方感知到异常,避免请求失败后无提示的静默问题。
内容的提问来源于stack exchange,提问作者coderodde
相关产品推荐
相关产品推荐

