You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript异步函数结合for循环处理天气数据渲染问题求助

问题描述

开发一款简易Web应用,通过地理、天气、图库三个异步API获取数据。需要遍历天气API返回的16天数据,替换原then链中的i变量,将所有日期的温度信息渲染到页面的<ul>标签中。尝试使用async for循环时出现错误:

16app.js:156 TypeError: Cannot read properties of undefined (reading 'lat') at forLoop (app.js:150:89)

错误原因分析
  • 重复调用无效API:循环中每次都调用getCity获取坐标,不仅浪费资源,还可能因API返回异常导致coords["geonames"][0]为undefined,触发读取lat属性的错误。
  • 变量作用域问题:forLoop中使用未声明的全局变量i、coords,异步执行时易出现变量覆盖或未初始化的情况。
  • 后端存储缺陷:server.js中weatherData是单个对象,每次POST都会覆盖之前的数据,无法存储16天的全部数据。
  • 渲染逻辑冗余:原receiveWeatherData只能处理单条数据,且循环传参但函数未接收,无法批量渲染。
解决方案

1. 优化异步流程

只获取一次城市坐标和天气数据,再遍历天气数据处理,避免重复调用API。

2. 修复后端存储

将weatherData改为数组,支持存储多条天气记录。

3. 简化渲染逻辑

直接在前端遍历天气数据并渲染,减少不必要的后端中转请求。

4. 规范变量声明

使用let/const声明变量,避免全局变量污染。

修改后的关键代码

前端app.js提交事件处理(替换原then链)

submitBtn.addEventListener("click", async (e) => {
    e.preventDefault();
    const city = document.getElementById("city").value;
    const departure = document.getElementById("date").value;
    const [depart_date, depart_time] = departure.split("T")
    const [depart_year, depart_month, depart_day] = depart_date.split("-")
    const [depart_hour, depart_minute] = depart_time.split(":")

    const future = new Date(depart_year, depart_month - 1, depart_day, depart_hour, depart_minute);

    // 修复条件判断逻辑
    if (city !== "" && departure !== "" && future > present) {
        document.getElementById("time").innerHTML = `Departure in ${Math.ceil((future - present) / 3600000 / 24)} days`;

        try {
            // 仅获取一次城市坐标
            const coords = await getCity(geoURL, city, geoUsername);
            if (!coords?.geonames?.[0]) throw new Error("无法获取城市坐标");
            
            // 获取16天天气数据
            const weatherData = await getWeather(weatherURL, weatherKey, coords.geonames[0].lat, coords.geonames[0].lng);
            if (!weatherData?.data?.length) throw new Error("无法获取天气数据");

            // 清空原有列表
            const entriesList = document.getElementById("entries");
            entriesList.innerHTML = "";

            // 遍历天气数据并渲染
            for (let i = 0; i < Math.min(16, weatherData.data.length); i++) {
                const dayData = weatherData.data[i];
                const node = document.createElement("li");
                node.textContent = `DATE: ${dayData.datetime}  TEMPERATURE: ${dayData.temp}`;
                entriesList.appendChild(node);
            }

            // 处理图片逻辑
            const picsData = await getPictures(city, pixabayURL, pixabayKey);
            if (picsData?.hits?.length) {
                const picIndex = Math.floor(Math.random() * picsData.hits.length);
                document.getElementById("city-pic").src = picsData.hits[picIndex].webformatURL;
            } else {
                throw new Error("未找到城市图片");
            }
        } catch (error) {
            console.log(error);
            alert(error.message || "操作失败,请检查输入或网络");
        }
    } else {
        alert("请输入有效城市和未来的出发时间");
    }
});

后端server.js修改(如需存储数据)

// 将单个对象改为数组存储多条天气数据
weatherData = [];

// 修改POST接口,追加数据而非覆盖
app.post("/addWeather", (req, res) => {
    weatherData.push({
        temp: req.body.temp,
        datetime: req.body.datetime
    });
    res.send(weatherData);
});

// 修改GET接口返回完整数组
app.get("/allWeather", function sendWeather(req, res) {
    res.send(weatherData);
});

内容的提问来源于stack exchange,提问作者Rohan Asif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 12:35:27