You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在执行fetch请求前等待经纬度值获取完成?

问题分析与解决方案

嗨,很高兴你已经通过切换到axios解决了请求错误的问题!我来帮你拆解下最初问题的核心原因,以及给出更规范的代码写法,方便你后续参考~

问题根源

你最初的代码里,navigator.geolocation.getCurrentPosition是异步API——它不会立刻返回位置数据,而是等浏览器获取到地理位置后,才会执行回调函数里的setLat和setLong。但你后面的fetch请求并没有等待这个异步操作完成就直接执行了,这时候lat和long还是初始的空值/默认值,拼出来的URL自然无效,导致错误请求。

正确的写法(含fetch和axios两种版本)

我们可以把getCurrentPosition封装成Promise,用async/await来控制异步流程,确保拿到有效经纬度后再发起请求:

1. 用fetch的修复版本

// 先把getCurrentPosition封装成Promise,方便用await控制
const getCurrentPosition = () => {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(resolve, reject);
  });
};

const fetchData = async () => {
  try {
    // 等待获取到位置数据
    const position = await getCurrentPosition();
    const lat = position.coords.latitude;
    const long = position.coords.longitude;
    
    // 更新状态
    setLat(lat);
    setLong(long);
    
    // 现在再拼URL发起请求
    const url = `https://api.openweathermap.org/data/2.5/weather/?lat=${lat}&lon=${long}&units=metric&APPID=DELETED`;
    const response = await fetch(url);
    const result = await response.json();
    setData(result);
  } catch (error) {
    console.error('获取数据失败:', error);
  }
};

// 调用函数,注意如果是在useEffect里,依赖项可以留空(因为我们已经在内部等待位置更新)
useEffect(() => {
  fetchData();
}, []);

2. 你提到的axios版本(更简洁)

axios会自动帮我们解析JSON响应,所以确实不需要手动调用response.json(),写法更清爽:

const getCurrentPosition = () => {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(resolve, reject);
  });
};

const fetchData = async () => {
  try {
    const position = await getCurrentPosition();
    const lat = position.coords.latitude;
    const long = position.coords.longitude;
    
    setLat(lat);
    setLong(long);
    
    const url = `https://api.openweathermap.org/data/2.5/weather/?lat=${lat}&lon=${long}&units=metric&APPID=DELETED`;
    // axios.get直接返回解析后的JSON,结果在data属性里
    const result = await axios.get(url);
    setData(result.data);
  } catch (error) {
    console.error('获取数据失败:', error);
  }
};

useEffect(() => {
  fetchData();
}, []);

额外提醒

原来的代码里把[lat, long]作为useEffect的依赖项,这其实会导致lat或long更新时重复调用fetchData,可能引发不必要的重复请求。按照上面的写法,我们把获取位置和请求数据的逻辑放在同一个异步流程里,useEffect的依赖项留空即可,只会在组件挂载时执行一次。

内容的提问来源于stack exchange,提问作者estin8

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 19:17:50