我正在尝试使用 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 得到的响应是一个错误,因为坐标作为未定义传递。
感谢所有帮助。
这是因为反应状态变量的更新不会立即发生。因此,您更新了 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 获取中获得了坐标。希望对您有帮助!