如何等待fetchData()完成后再执行依赖其数据的fetchForecastData()?
解决顺序调用fetchData和fetchForecastData的问题
你的核心问题是两个异步函数执行顺序混乱,且依赖的lat/lon状态更新是异步的,导致fetchForecastData经常拿到初始空值发起无效请求,重启时这个问题更明显。下面给你两种靠谱的解决方案:
方案一:直接传递参数顺序执行(推荐,避免状态依赖)
修改fetchData让它返回获取到的经纬度,然后在useEffect里按顺序执行,直接把经纬度传给fetchForecastData,绕开React状态更新的异步延迟问题:
function App() { const [location, setLocation] = useState(''); const [currentWeather, setCurrentWeather] = useState([]); const [weatherForecast, setWeatherForecast] = useState([]); const [lat, setLat] = useState(''); const [lon, setLon] = useState(''); const addSearchCity = (search) => { setLocation(search); }; // 修改fetchData,返回经纬度 const fetchData = async () => { const res = await axios( `https://api.openweathermap.org/data/2.5/weather?q=london&appid={API}&units=metric`, ); setCurrentWeather(res.data); const { lat, lon } = res.data.coord; setLat(lat); setLon(lon); return { lat, lon }; // 返回经纬度 }; // 修改fetchForecastData,支持接收参数 const fetchForecastData = async (lat, lon) => { const result = await axios( `https://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${lon}&appid={API}&units=metric`, ); setWeatherForecast(result); }; useEffect(() => { // 内部封装async函数,保证顺序执行 const fetchAllData = async () => { const coords = await fetchData(); // 拿到经纬度后再调用预报接口 await fetchForecastData(coords.lat, coords.lon); }; fetchAllData(); }, []); }
方案二:监听经纬度状态变化触发请求
利用React的状态依赖特性,当lat和lon更新为有效值时,自动调用fetchForecastData:
function App() { const [location, setLocation] = useState(''); const [currentWeather, setCurrentWeather] = useState([]); const [weatherForecast, setWeatherForecast] = useState([]); // 初始设为null,方便判断是否有有效值 const [lat, setLat] = useState(null); const [lon, setLon] = useState(null); const addSearchCity = (search) => { setLocation(search); }; const fetchData = async () => { const res = await axios( `https://api.openweathermap.org/data/2.5/weather?q=london&appid={API}&units=metric`, ); setCurrentWeather(res.data); setLat(res.data.coord.lat); setLon(res.data.coord.lon); }; const fetchForecastData = async () => { // 先判断经纬度是否有效,避免无效请求 if (!lat || !lon) return; const result = await axios( `https://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${lon}&appid={API}&units=metric`, ); setWeatherForecast(result); }; // 初始加载只调用当前天气接口 useEffect(() => { fetchData(); }, []); // 监听lat和lon变化,有值时调用预报接口 useEffect(() => { fetchForecastData(); }, [lat, lon]); }
原代码重启异常的原因
原useEffect里同时调用两个异步函数,fetchForecastData会先执行,此时lat和lon还是初始空字符串,发起的请求参数无效导致接口报错。重启时组件重新初始化,这个问题会重复出现。上面两种方案都能解决:
- 方案一通过
await强制顺序,直接传递参数,完全不依赖状态更新时机; - 方案二通过状态监听+有效值判断,确保只有拿到有效经纬度才发起请求。
内容的提问来源于stack exchange,提问作者Mliki Mliki
相关产品推荐
相关产品推荐

