Axios请求返回undefined问题排查及代码优化咨询
问题原因分析
问题出在coordinatesToPlaceID函数——这个async函数没有返回有效结果。你在await cityToCoordinates(cityName).then(...)的回调里return了Axios请求的结果,但这个return属于then的回调函数,并非coordinatesToPlaceID函数本身的返回。async函数如果没有显式return,默认会返回一个resolve为undefined的Promise,因此placeIDToCurrentForecast里拿到的response自然是undefined。
修复与代码优化
核心问题修复
修改coordinatesToPlaceID,让它返回正确的Promise结果:
const coordinatesToPlaceID = async (cityName) => { const coordinatesToPlaceApiURL = "http://dataservice.accuweather.com/locations/v1/cities/geoposition/search"; const accuWeatherApiKey = "ACCUWEATHER_API_KEY"; // 用await替代then,避免嵌套 const coords = await cityToCoordinates(cityName); if (!coords) return; // 处理城市不存在的情况 const query = `${coords.latitude},${coords.longitude}`; const queryUrlEncoded = encodeURIComponent(query); try { const response = await axios.get( `${coordinatesToPlaceApiURL}?q=${queryUrlEncoded}&apikey=${accuWeatherApiKey}` ); console.log(response.data.Key); return response.data.Key; } catch (error) { console.log("An error has occured in coordinates to place ID"); // 可抛出错误让上层处理,或返回undefined // throw error; } };
整体优化方案
- 统一使用async/await,禁用then混用:让代码层级更扁平,彻底避免回调嵌套,提升可读性。
- 严谨错误处理:不要仅打印错误日志,必要时抛出错误让上层函数处理,或返回明确的无效标识(如null)。
- 修正拼写错误:比如
mapbowAcessToken改为mapboxAccessToken,weathr改为weather。 - 提取全局常量:将API密钥、基础URL等常量抽离到函数外部,方便统一维护。
- 增加空值校验:拿到坐标、PlaceID后先判断有效性,再执行后续逻辑。
优化后的完整代码:
const axios = require("axios").default || require("axios"); // 全局常量统一维护 const MAPBOX_TOKEN = "MAPBOX_TOKEN"; const ACCUWEATHER_API_KEY = "ACCUWEATHER_API_KEY"; const GEOCODE_BASE_URL = "https://api.mapbox.com/geocoding/v5/mapbox.places/"; const COORDINATES_TO_PLACE_URL = "http://dataservice.accuweather.com/locations/v1/cities/geoposition/search"; const CURRENT_WEATHER_URL = "http://dataservice.accuweather.com/currentconditions/v1/"; const cityToCoordinates = async (cityName) => { try { const cityNameUrlEncoded = encodeURIComponent(cityName); const response = await axios.get( `${GEOCODE_BASE_URL}${cityNameUrlEncoded}.json?access_token=${MAPBOX_TOKEN}&limit=1` ); const responseObject = response.data; if (responseObject.features.length === 0) { console.log("Sorry no such place exists"); return null; } const [longitude, latitude] = responseObject.features[0].center; return { latitude, longitude }; } catch (error) { console.log("An error has occured in city to coordinates"); return null; } }; const coordinatesToPlaceID = async (cityName) => { try { const coords = await cityToCoordinates(cityName); if (!coords) return null; const query = `${coords.latitude},${coords.longitude}`; const queryUrlEncoded = encodeURIComponent(query); const response = await axios.get( `${COORDINATES_TO_PLACE_URL}?q=${queryUrlEncoded}&apikey=${ACCUWEATHER_API_KEY}` ); return response.data.Key; } catch (error) { console.log("An error has occured in coordinates to place ID"); return null; } }; const placeIDToCurrentForecast = async (cityName) => { try { const placeId = await coordinatesToPlaceID(cityName); if (!placeId) { console.log("There is no valid place ID"); return; } const response = await axios.get( `${CURRENT_WEATHER_URL}${placeId}?apikey=${ACCUWEATHER_API_KEY}` ); const temp = response.data[0].Temperature.Metric.Value; console.log(`The current weather in ${cityName} is ${temp}° C`); } catch (error) { console.log("An error has occured in place ID to current forecast"); } }; placeIDToCurrentForecast("California");
内容的提问来源于stack exchange,提问作者Starnec
相关产品推荐
相关产品推荐

