如何防止异步API调用后加载浏览器坐标?

问题描述 投票:0回答:1

我正在尝试使用 React 加载天气数据,为此您需要浏览器坐标。我尝试过使用异步和同步进行加载,在这两种情况下,它都不会在异步 API 响应之前加载。如何预防?

    const fetchBrowserCoordinates = () => {
    if (!navigator.geolocation) {
        console.log('GeoLocation is not supported by your browser.');
    } else {
        console.log('Loading.');
        navigator.geolocation.getCurrentPosition((position) => {
                console.log('Loaded coordinates.');
                setCoords(position.coords);
            },
            () => { console.log('Unable to retrieve your location.'); }
        );
    }
}
  useEffect(() => {
    fetchRealTimeWeatherData();
  }, []);

const fetchRealTimeWeatherData = async () => {
    fetchBrowserCoordinates();

    const API_KEY = '____YOUR____API____KEY____';
    const location = coords.latitude + ',' + coords.longitude;

    await fetch('https://api.tomorrow.io/v4/weather/realtime?units=imperial&location=' + location + '&apikey=' + API_KEY, options)
      .then(response => response.json())
      .then(response => setWeather(response))
      .catch(err => console.error(err));

    console.log(weather);
}

我从 API 得到的响应是一个错误,因为坐标作为未定义传递。

https://api.tomorrow.io/v4/weather/realtime?units=imperial&location=undefined,undefined&apikey=____您的____API____KEY____ 400

感谢所有帮助。

javascript reactjs asynchronous async-await fetch
1个回答
0
投票

这是因为反应状态变量的更新不会立即发生。因此,您更新了 coords 变量,但是当您访问纬度/经度属性时,coords 变量尚未更新。我的建议是重构

fetchBrowserCoordinates
以直接返回坐标,如下所示:

const fetchBrowserCoordinates = async () => {
    return new Promise((resolve, reject) => {
    if (!navigator.geolocation) {
        reject("Not available");
    } else {
        navigator.geolocation.getCurrentPosition((position) => {
                resolve(position);
            },
            reject
        );
    }
    });
}

然后您可以像这样从 API 获取数据:

const fetchRealTimeWeatherData = async () => {
    const newCoords = await fetchBrowserCoordinates();

    const API_KEY = '____YOUR____API____KEY____';
    const location = newCoords.latitude + ',' + newCoords.longitude;

    await fetch('https://api.tomorrow.io/v4/weather/realtime?units=imperial&location=' + location + '&apikey=' + API_KEY, options)
      .then(response => response.json())
      .then(response => setWeather(response))
      .catch(err => console.error(err));

    console.log(weather); // this won't show the latest response due to reasons explained above
    setCoords(newCoords);
}

您也可以只执行

fetchBrowserCoordinates
一次,例如如果他们之前已经从天气 API 获取中获得了坐标。希望对您有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.