关于与异步函数相关的 React 组件 运行 的顺序问题

Question About Which Order React Components Run In Relation To Async Functions

我有一个应用程序,在用户加载它时,使用 Javascript 的内置 API 来获取地理定位数据。然后,它将此数据传递给一个组件,该组件应该在对 OpenWeather 的 API 调用中使用它。但是,API 调用在 Geolocation 可以加载之前就已经发生了。我已经尝试让我的 useLocation 函数异步等待(成功)但是它没有用。

这是我的 App.js

的代码
 const useLocation = () => {
  const [location, setLocation] = useState({lat: 0, long: 0})

    useEffect(()=>{
      const success = (position) =>{ 
        let lat = position.coords.latitude
        let long = position.coords.longitude
   
        
        console.log(lat, long)
        setLocation({lat: lat, long: long})
        
      }
       navigator.geolocation.getCurrentPosition(success)

    },[])

    return location;

}


function App() {
  // Gets just the
 const location = useLocation()

function App() {
  // Gets just the
 const location = useLocation()
    
  const routes = ['nasa','openweather','zomato']

  return ( 
    <div className="App"> 

 

      <Route exact path="/openweather">
        <Weather position={location} />
      </Route>

</div>

}

这是 Weather.js

的代码
import { useState, useEffect } from "react"

const Weather = ({ position }) => {

    const long = position.long
    const lati = position.lat

    const APIKey = '1234'

    const [weather, setWeather] = useState()

    const initData = async () => {
        const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${lati}&lon=${long}&appid=${APIKey}`)
        
        const weatherData = await response.json()
            setWeather(weatherData)


        console.log(response)
    }

    useEffect(()=> {
        initData()
    },[])

Geolocation getCurrentPosition 在函数回调 success 上获取结果是异步的

const success = (position) => { 
  const lat = position.coords.latitude
  const long = position.coords.longitude

  console.log(lat, long)
}

navigator.geolocation.getCurrentPosition(success)
console.log('I will log before geolocation gets position')

为了使其同步,我们需要将它们包装在一个 Promise 中,并将 resolve 放在 success 回调函数中。

const geolocationGetCurrentPosition = () => {
  return new Promise((resolve, reject) => {
    const success = (position) => {
      const lat = position.coords.latitude;
      const long = position.coords.longitude;

      resolve({ lat, long });
    };
    const error = (err) => {
      reject(err);
    };
    navigator.geolocation.getCurrentPosition(success, error);
  });
};

const run = async () => {
  await geolocationGetCurrentPosition()
  console.log("I'm synchronous, I will log after geolocation gets position")
}

这是结果代码,但我将默认位置状态更改为空,因为经度和纬度值设置为零是有效坐标。

const geolocationGetCurrentPosition = () => {
  return new Promise((resolve, reject) => {
    const success = (position) => {
      const lat = position.coords.latitude;
      const long = position.coords.longitude;

      resolve({ lat, long });
    };
    const error = (err) => {
      reject(err);
    };
    navigator.geolocation.getCurrentPosition(success, error);
  });
};

const useLocation = () => {
  const [location, setLocation] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const { lat, long } = await geolocationGetCurrentPosition();
        setLocation({ lat, long });
      } catch (err) {
        // err
      }
    }
    fetchData();
  }, []);

  return location;
};

function App() {
  const location = useLocation();

  const routes = ["nasa", "openweather", "zomato"];

  return (
    <div className="App">
      {location && (
        <Route exact path="/openweather">
          <Weather position={location} />
        </Route>
      )}
    </div>
  );
}