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

Promise链式调用问题:通过OpenWeatherMap API获取当前及5天天气

问题排查与修复方案

核心问题分析

  • 错误访问weekWeatherUrl:原代码中data.weekWeatherUrl完全错误,data是第一个API返回的天气数据对象,不存在weekWeatherUrl字段,应直接使用函数内预定义的weekWeatherUrl变量。
  • this指向丢失:.then()的普通函数回调中,this指向并非weatherData对象,导致调用this.unveilWeather时会报错。可改用箭头函数,或提前保存this引用。
  • 函数名不匹配:对象内定义的方法是getWeatherInfo,但调用时用了getCurrentWeatherInfo,导致找不到函数抛出错误。
  • 未处理双API数据:原代码仅处理了第二个API的返回结果,没有分别处理当前天气和5天预报的逻辑。
  • async/await使用误区:对象方法可直接声明为async function,通过await简化异步请求的处理流程。

修复后的代码(推荐async/await版本,更易读)

// 先替换为你的OpenWeatherMap API密钥
const currentWeatherApiTag = "你的API密钥";
const weekForecastApiTag = "你的API密钥";

const weatherData = {
  // 改为async方法,并行获取双API数据
  async getWeatherInfo(city) {
    const currentWeatherUrl = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${currentWeatherApiTag}`;
    const weekWeatherUrl = `https://api.openweathermap.org/data/2.5/forecast?q=${city}&units=imperial&appid=${weekForecastApiTag}`;

    try {
      // 并行请求两个API,提升效率
      const [currentResponse, weekResponse] = await Promise.all([
        fetch(currentWeatherUrl),
        fetch(weekWeatherUrl)
      ]);

      const currentData = await currentResponse.json();
      const weekData = await weekResponse.json();

      // 分别渲染当前天气和5天预报
      this.displayCurrentWeather(currentData);
      this.displayWeekForecast(weekData);
    } catch (error) {
      console.error("获取天气数据失败:", error);
      // 可在此添加用户可见的错误提示
    }
  },

  // 拆分渲染逻辑:当前天气
  displayCurrentWeather(data) {
    const { name } = data;
    const { icon, description } = data.weather[0];
    const { temp, humidity } = data.main;
    const { speed } = data.wind;

    document.querySelector("#City").innerText = `Weather in ${name}`;
    document.querySelector(".weather-icon").src = `http://openweathermap.org/img/wn/${icon}.png`;
    document.querySelector("#CityWeatherDescription").innerText = description;
    document.querySelector("#Temperature").innerText = `${temp} °F`;
    document.querySelector(".humidity-weather-stat").innerText = `Humidity : ${humidity}%`;
    document.querySelector(".wind-speed-weather-stat").innerText = `Wind Speed : ${speed} m/hr`;
  },

  // 新增:渲染5天预报逻辑
  displayWeekForecast(data) {
    // 筛选每天中午12点的预报数据(OpenWeatherMap返回每3小时一条数据)
    const dailyForecasts = data.list.filter(item => item.dt_txt.includes("12:00:00"));
    const forecastContainer = document.querySelector("#WeekForecast"); // 需确保页面存在该容器
    forecastContainer.innerHTML = ""; // 清空旧数据

    dailyForecasts.forEach(forecast => {
      const date = new Date(forecast.dt * 1000).toLocaleDateString();
      const { icon } = forecast.weather[0];
      const { temp } = forecast.main;

      // 创建预报卡片元素
      const forecastCard = document.createElement("div");
      forecastCard.className = "forecast-card";
      forecastCard.innerHTML = `
        <p>${date}</p>
        <img src="http://openweathermap.org/img/wn/${icon}.png" alt="weather icon">
        <p>${temp} °F</p>
      `;
      forecastContainer.appendChild(forecastCard);
    });
  },

  searchCurrentWeather() {
    const city = document.querySelector("#Search-Bubble").value.trim();
    if (city) {
      this.getWeatherInfo(city);
    }
  },
};

// 事件监听
document.getElementById("SearchBtn").addEventListener("click", () => {
  weatherData.searchCurrentWeather();
});

document.getElementById("Search-Bubble").addEventListener("keyup", (event) => {
  if (event.key === "Enter") {
    weatherData.searchCurrentWeather();
  }
});

// 初始化加载Brooklyn的天气
weatherData.getWeatherInfo("Brooklyn");

关键修复点说明

  1. API请求优化:用Promise.all并行请求两个API,比链式调用效率更高,若需顺序请求也可改为依次await。
  2. this指向修正:事件回调用箭头函数,确保this指向weatherData;async方法内直接使用this即可。
  3. 逻辑拆分:将当前天气和5天预报的渲染拆分为独立方法,避免代码冗余,提升可维护性。
  4. 错误处理:添加try/catch捕获异步请求和数据解析时的错误,避免页面崩溃。
  5. 函数名统一:将调用与定义的函数名统一为getWeatherInfo,解决函数未找到的问题。

链式Promise版本(若坚持使用链式调用)

const currentWeatherApiTag = "你的API密钥";
const weekForecastApiTag = "你的API密钥";

const weatherData = {
  getWeatherInfo(city) {
    const currentWeatherUrl = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${currentWeatherApiTag}`;
    const weekWeatherUrl = `https://api.openweathermap.org/data/2.5/forecast?q=${city}&units=imperial&appid=${weekForecastApiTag}`;
    const self = this; // 提前保存this指向

    fetch(currentWeatherUrl)
      .then(response => response.json())
      .then(currentData => {
        self.displayCurrentWeather(currentData);
        return fetch(weekWeatherUrl); // 直接使用预定义的URL变量
      })
      .then(response => response.json())
      .then(weekData => {
        self.displayWeekForecast(weekData);
      })
      .catch(error => {
        console.error("获取天气数据失败:", error);
      });
  },

  // 以下displayCurrentWeather和displayWeekForecast方法与上面一致
  displayCurrentWeather(data) { /* ... */ },
  displayWeekForecast(data) { /* ... */ },
  searchCurrentWeather() { /* ... */ },
};

// 事件监听和初始化逻辑与上面一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:50:45