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

为何自定义getWeatherData函数返回undefined而非预期数组?

解决异步函数返回undefined的问题

嘿,这个坑我踩过好多次!你遇到的是异步JavaScript的经典问题——fetch是异步操作,你的getWeatherData函数根本没有返回任何东西,所以外部调用它的时候自然拿到undefined。

问题根源

你写的.then里的return只是给那个回调函数用的,不是getWeatherData函数的返回值。fetch发起请求后,getWeatherData函数会立刻执行完(因为异步操作不会阻塞代码),此时函数没有返回值,所以values就是undefined。等fetch请求完成后,.then里的代码才会跑,但这时候外部的console.log(values)早就执行完了。

修复方案

我们需要让getWeatherData返回整个fetch的Promise链,这样外部就能通过.then或者async/await来获取异步操作的结果。

方案1:用Promise链式调用(保持原风格)

let city = "London"
// 外部通过.then接收结果
getWeatherData(city, "en")
  .then(values => {
    console.log(values); // 这里就能拿到正确的数组了
  })
  .catch(err => console.error("获取数据失败:", err));

function getWeatherData(city, lang) {
  // 关键:返回整个fetch的Promise链
  return fetch(`http://api.openweathermap.org/geo/1.0/direct?q=${city}&limit=1&appid={My_API_Key}`)
    .then(response => {
      // 新增:检查请求是否成功(比如404、500这些情况)
      if (!response.ok) {
        throw new Error(`请求失败,状态码: ${response.status}`);
      }
      return response.json();
    })
    .then(data => {
      // 新增:检查API是否返回有效数据
      if (!data || data.length === 0) {
        throw new Error("未找到该城市的信息");
      }
      // 用可选链避免local_names中没有对应lang的情况,同时fallback到默认城市名
      const cityName = data[0]['local_names']?.[lang] || data[0]['name'];
      const cityCountryname = data[0]['country'];
      const cityLat = data[0]['lat'];
      const cityLon = data[0]['lon'];
      return [cityCountryname, cityName, cityLat, cityLon];
    })
    .catch(err => {
      console.error("内部错误:", err);
      throw err; // 把错误抛出去,让外部能捕获处理
    });
}

方案2:用async/await(更易读的现代写法)

如果你的环境支持ES2017+,推荐用async/await,异步代码看起来像同步的,可读性更高:

// 把函数标记为async
async function getWeatherData(city, lang) {
  try {
    const response = await fetch(`http://api.openweathermap.org/geo/1.0/direct?q=${city}&limit=1&appid={My_API_Key}`);
    if (!response.ok) {
      throw new Error(`请求失败,状态码: ${response.status}`);
    }
    const data = await response.json();
    if (!data || data.length === 0) {
      throw new Error("未找到该城市的信息");
    }
    const cityName = data[0]['local_names']?.[lang] || data[0]['name'];
    const cityCountryname = data[0]['country'];
    const cityLat = data[0]['lat'];
    const cityLon = data[0]['lon'];
    return [cityCountryname, cityName, cityLat, cityLon];
  } catch (err) {
    console.error("获取数据出错:", err);
    throw err;
  }
}

// 调用时需要在async函数里用await
(async () => {
  let city = "London";
  try {
    const values = await getWeatherData(city, "en");
    console.log(values);
  } catch (err) {
    console.error("外部处理错误:", err);
  }
})();

几个额外的小建议

  • 永远要处理异步操作的错误,包括网络失败、API返回错误状态码、数据为空这些情况
  • 用模板字符串代替字符串拼接,代码更干净(比如${city})
  • 用可选链?.避免访问不存在的属性时抛出错误(比如data[0]['local_names']?.[lang])
  • 如果API返回的local_names里没有你指定的语言,可以fallback到默认的name字段,提升用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:02:28