JavaScript实战④|天气查询应用,调用API与异步处理
author: 专注前端开发分享JavaScript干货title: JavaScript实战④天气查询应用调用API与异步处理update: 2026-04-28tags: JavaScript,实战项目,天气应用,API调用,异步处理,Fetch,Promise作者专注前端开发分享JavaScript干货更新时间2026年4月适合人群掌握JS基础想学习API调用和异步处理的开发者前言为什么做这个项目天气应用是练习 API 调用的最佳项目学习 Fetch API处理异步数据错误处理动态更新 UI一、项目功能 输入城市名称查询天气️ 显示当前温度、天气状况 显示湿度、风速、气压等详情 显示未来几天预报⏱️ 加载状态提示❌ 错误处理二、HTML 结构!DOCTYPEhtmlhtmllangzh-CNheadmetacharsetUTF-8metanameviewportcontentwidthdevice-width, initial-scale1.0title天气查询/titlestyle*{margin:0;padding:0;box-sizing:border-box;}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);min-height:100vh;padding:50px 20px;}.container{max-width:500px;margin:0 auto;}h1{text-align:center;color:white;margin-bottom:30px;font-size:2.5rem;}.search-box{display:flex;gap:10px;margin-bottom:30px;}#cityInput{flex:1;padding:15px 20px;border:none;border-radius:50px;font-size:16px;outline:none;box-shadow:0 4px 15pxrgba(0,0,0,0.2);}#searchBtn{padding:15px 30px;background:#ff6b6b;color:white;border:none;border-radius:50px;cursor:pointer;font-size:16px;transition:transform 0.3s,background 0.3s;}#searchBtn:hover{transform:scale(1.05);background:#ff5252;}#searchBtn:disabled{background:#ccc;cursor:not-allowed;transform:none;}.weather-card{background:rgba(255,255,255,0.95);border-radius:20px;padding:30px;box-shadow:0 10px 40pxrgba(0,0,0,0.2);display:none;}.weather-card.show{display:block;animation:fadeIn 0.5s ease;}keyframesfadeIn{from{opacity:0;transform:translateY(20px);}to{opacity:1;transform:translateY(0);}}.city-name{font-size:2rem;color:#333;margin-bottom:10px;}.weather-main{display:flex;align-items:center;justify-content:center;gap:20px;margin:20px 0;}.temperature{font-size:4rem;font-weight:bold;color:#667eea;}.weather-icon{font-size:4rem;}.weather-desc{text-align:center;font-size:1.2rem;color:#666;margin-bottom:20px;}.weather-details{display:grid;grid-template-columns:repeat(3,1fr);gap:15px;margin-top:20px;}.detail-item{text-align:center;padding:15px;background:#f8f9fa;border-radius:10px;}.detail-label{color:#999;font-size:0.9rem;margin-bottom:5px;}.detail-value{color:#333;font-size:1.2rem;font-weight:bold;}.loading{text-align:center;color:white;font-size:1.2rem;display:none;}.loading.show{display:block;}.error{background:#ff6b6b;color:white;padding:15px 20px;border-radius:10px;text-align:center;display:none;}.error.show{display:block;animation:shake 0.5s ease;}keyframesshake{0%, 100%{transform:translateX(0);}25%{transform:translateX(-10px);}75%{transform:translateX(10px);}}/style/headbodydivclasscontainerh1️ 天气查询/h1divclasssearch-boxinputtypetextidcityInputplaceholder输入城市名称如北京buttonidsearchBtn查询/button/divdivclassloadingidloading正在查询.../divdivclasserroriderror/divdivclassweather-cardidweatherCardh2classcity-nameidcityName/h2divclassweather-maindivclasstemperatureidtemperature/divdivclassweather-iconidweatherIcon/div/divdivclassweather-descidweatherDesc/divdivclassweather-detailsdivclassdetail-itemdivclassdetail-label湿度/divdivclassdetail-valueidhumidity/div/divdivclassdetail-itemdivclassdetail-label风速/divdivclassdetail-valueidwindSpeed/div/divdivclassdetail-itemdivclassdetail-label气压/divdivclassdetail-valueidpressure/div/div/div/div/divscriptsrcapp.js/script/body/html三、JavaScript 实现// 使用 OpenWeatherMap API需要注册获取 API Key// 或者使用免费的 wttr.in 服务constAPI_BASEhttps://wttr.in;classWeatherApp{constructor(){this.cityInputdocument.getElementById(cityInput);this.searchBtndocument.getElementById(searchBtn);this.loadingdocument.getElementById(loading);this.errordocument.getElementById(error);this.weatherCarddocument.getElementById(weatherCard);this.bindEvents();}bindEvents(){this.searchBtn.addEventListener(click,()this.search());this.cityInput.addEventListener(keypress,(e){if(e.keyEnter)this.search();});}asyncsearch(){constcitythis.cityInput.value.trim();if(!city){this.showError(请输入城市名称);return;}this.showLoading();this.hideError();this.hideWeather();try{constweatherawaitthis.fetchWeather(city);this.displayWeather(weather);}catch(err){this.showError(查询失败请检查城市名称是否正确);console.error(err);}finally{this.hideLoading();}}asyncfetchWeather(city){// 使用 wttr.in 免费 APIconstresponseawaitfetch(${API_BASE}/${encodeURIComponent(city)}?formatj1);if(!response.ok){thrownewError(API 请求失败);}constdataawaitresponse.json();// 解析 wttr.in 的数据格式constcurrentdata.current_condition[0];return{city:data.nearest_area[0].areaName[0].value,temperature:current.temp_C,feelsLike:current.FeelsLikeC,description:current.lang_zh?current.lang_zh[0].value:current.weatherDesc[0].value,humidity:current.humidity,windSpeed:current.windspeedKmph,pressure:current.pressure,icon:this.getWeatherIcon(current.weatherCode)};}getWeatherIcon(code){// 天气代码对应的表情consticonMap{113:☀️,// 晴天116:⛅,// 多云119:☁️,// 阴天122:☁️,// 阴天143:️,// 雾176:️,// 小雨179:️,// 雨夹雪182:️,// 雨夹雪185:️,// 毛毛雨200:⛈️,// 雷暴227:️,// 阵雪230:❄️,// 暴雪248:️,// 雾260:️,// 冻雾263:️,// 小雨266:️,// 中雨281:️,// 冻雨284:️,// 大冻雨293:️,// 小雨296:️,// 中雨299:️,// 大雨302:️,// 暴雨305:️,// 阵雨308:️,// 大暴雨311:️,// 冻雨314:️,// 大冻雨317:️,// 雨夹雪320:️,// 大雪323:️,// 阵雪326:️,// 中雪329:❄️,// 大雪332:❄️,// 大雪335:❄️,// 暴雪338:❄️,// 大暴雪350:,// 冰粒353:️,// 阵雨356:️,// 大雨359:️,// 暴雨362:️,// 阵雪365:️,// 大雪368:️,// 阵雪371:❄️,// 大雪374:,// 冰粒377:,// 冰粒386:⛈️,// 雷暴伴雨389:⛈️,// 雷暴伴大雨392:⛈️,// 雷暴伴雪395:⛈️,// 雷暴伴暴雪};returniconMap[code]||️;}displayWeather(weather){document.getElementById(cityName).textContentweather.city;document.getElementById(temperature).textContent${weather.temperature}°C;document.getElementById(weatherIcon).textContentweather.icon;document.getElementById(weatherDesc).textContent${weather.description}| 体感${weather.feelsLike}°C;document.getElementById(humidity).textContent${weather.humidity}%;document.getElementById(windSpeed).textContent${weather.windSpeed}km/h;document.getElementById(pressure).textContent${weather.pressure}hPa;this.weatherCard.classList.add(show);}showLoading(){this.loading.classList.add(show);this.searchBtn.disabledtrue;}hideLoading(){this.loading.classList.remove(show);this.searchBtn.disabledfalse;}showError(message){this.error.textContentmessage;this.error.classList.add(show);}hideError(){this.error.classList.remove(show);}hideWeather(){this.weatherCard.classList.remove(show);}}// 初始化应用constappnewWeatherApp();四、知识点回顾知识点应用fetch()发送 HTTP 请求async/await处理异步操作try/catch错误处理encodeURIComponentURL 编码JSON.parse()解析 JSON 数据动态 UI根据数据显示/隐藏元素五、扩展功能地理定位自动获取当前位置天气历史记录保存查询过的城市未来预报显示未来 3-5 天天气温度单位切换摄氏度/华氏度六、课后作业添加获取当前位置天气功能使用 Geolocation API实现温度单位切换摄氏度/华氏度添加本地存储保存最近查询的城市有问题欢迎评论区留言大家一起讨论标签JavaScript | 实战项目 | 天气应用 | API调用 | 异步处理 | Fetch | Promise