天气应用每5秒调用async函数更新数据时遇400及未定义属性错误
问题分析与解决方案
核心问题
- 400错误原因:你在
checkWeather函数末尾执行了input.value = '',当setInterval触发下一次自动更新时,input.value是空字符串,导致API请求的q(城市)参数为空,不符合OpenWeatherMap API的要求,直接返回400错误。 - "Cannot read properties of undefined"错误:API返回400错误时,响应数据里没有
main字段(此时返回的是错误信息结构),直接访问data.main.temp就会触发读取undefined属性的报错。
修复步骤
维护当前更新的城市变量
添加一个变量存储最后一次确认的城市,避免依赖可能被清空或修改的input值:let currentCity = 'New York'; // 初始默认城市修改用户提交逻辑
只有在用户主动提交(点击按钮或回车)时,才更新currentCity并清空input,而不是每次调用checkWeather都清空:button.addEventListener('click', () => { const inputVal = input.value.trim(); if (inputVal) { currentCity = inputVal; checkWeather(); clearInterval(intervalID); intervalID = setInterval(checkWeather, 5000); input.value = ''; // 仅在用户提交后清空输入框 } }); input.addEventListener('keyup', (event) => { if (event.key === 'Enter') { const inputVal = input.value.trim(); if (inputVal) { currentCity = inputVal; checkWeather(); clearInterval(intervalID); intervalID = setInterval(checkWeather, 5000); input.value = ''; } } });调整API请求的参数来源
修改checkWeather函数,用currentCity而非input.value发起请求,同时增加响应状态检查提前捕获HTTP错误:async function checkWeather(){ try { const response = await fetch(apiURL + `&q=${currentCity}&appid=${APIkey}`); if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } const data = await response.json(); // 后续DOM更新逻辑保持不变 const temp = document.querySelector('.temp'); temp.textContent = `${data.main.temp}°c`; const city = document.querySelector('.city'); city.textContent = data.name; const windspeed = document.querySelector('.windspeed'); windspeed.textContent = `${data.wind.speed} km/h`; const humidity = document.querySelector('.humid'); humidity.textContent = `${data.main.humidity} %`; const clouds = document.querySelector('.cloud'); clouds.setAttribute('src',`images/${data.weather[0].main.toLowerCase()}.png`); console.log(data.main); } catch (error) { console.log('发生错误:', error.message); const errorMsg = document.querySelector('.error-message'); if (errorMsg) errorMsg.style.display = 'block'; } }可选:优化请求频率
OpenWeatherMap免费版有请求次数限制(60次/分钟),5秒一次的调用频率(12次/分钟)在限额内,但如果后续遇到限流问题,可以将间隔调整到10-15秒,降低触发限制的风险。
内容的提问来源于stack exchange,提问作者user823324
相关产品推荐
相关产品推荐

