JavaScript天气小部件全局经纬度变量在geolocation成功回调中未更新问题
问题根源
你遇到的不是全局变量更新失败的问题,而是异步API执行顺序导致的逻辑错误:
navigator.geolocation.getCurrentPosition是异步非阻塞接口,调用后会立刻执行后续代码,不会等待定位成功的success回调触发- 你在调用定位接口后立刻执行了
fetchWeather,此时success回调还没运行,自然拿不到更新后的经纬度值
另外原代码还有两个隐性bug:
fetchWeather中response.json()也是异步方法,缺少await关键字,拿到的返回值是Promise对象而非实际的天气数据- 缺少定位失败后的默认经纬度兜底,会导致天气接口请求参数异常
修复方案
把天气请求逻辑和定位回调绑定,等定位完成后再发起天气请求,同时补充错误兜底和异步等待逻辑,修复后完整代码如下:
修复后的JS代码
setInterval(showWeather, 900000); setTimeout(showWeather,1000) function showWeather(){ var appid = "API_KEY_FOR_OPENWEATHERMAP"; // 可自行修改默认经纬度,定位失败时使用 const DEFAULT_LAT = 39.9042; const DEFAULT_LON = 116.4074; var latitude = DEFAULT_LAT; var longitude = DEFAULT_LON; async function fetchWeather(){ var url = `https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${appid}&units=metric` const response = await fetch(url); // 补充await等待json解析完成 const data = await response.json(); return data } // 抽离公共渲染逻辑,减少重复代码 function renderWeather(data) { const icon = data.weather[0].icon; document.getElementById("city").innerHTML = data.name; document.getElementById("temp").innerHTML = data.main.temp + "°"; const iconUrl = `https://openweathermap.org/img/w/${icon}.png`; document.getElementById("wicon").src = iconUrl; } function success(position){ latitude = position.coords.latitude; longitude = position.coords.longitude; fetchWeather().then(renderWeather) } function error(){ console.log('定位获取失败,将展示默认地区天气') fetchWeather().then(renderWeather) } if(navigator.geolocation){ navigator.geolocation.getCurrentPosition(success, error); }else{ console.log("当前设备不支持定位功能,将展示默认地区天气") fetchWeather().then(renderWeather) } }
HTML代码无需修改
<h5 id="city">User Location</h5> <div> <img id="wicon" src="https://openweathermap.org/img/w/01d.png" alt="Weather icon"> <strong id="temp">Temperature°</strong> </div>
内容的提问来源于stack exchange,提问作者Ashis Sahoo
相关产品推荐
相关产品推荐

