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

为何JavaScript中全局变量在异步函数外打印为undefined?

问题

声明了全局变量latitude、longitude、IPLocation,调用异步函数start为变量赋值后,在函数外打印IPLocation显示undefined,但在start函数内打印该变量却正常。代码如下:

let latitude, longitude, IPLocation;
start(path)
console.log(IPLocation) // 输出undefined

async function start(path) {
IPLocation = await getData(path);
latitude = IPLocation.location.lat;
longitude = IPLocation.location.lng;
console.log(IPLocation) // 正常输出数据
}

async function getData(path) {
const data = await fetch(path);
const scrampled = await data.json();
parsed = await JSON.parse(JSON.stringify(scrampled));
return parsed
}
原因

核心是异步函数的执行特性:

  • start是异步函数,调用它时会立即返回一个Promise,不会阻塞后续代码的执行。
  • 你调用start(path)后立刻执行console.log(IPLocation),这时候await getData(path)还没完成(网络请求仍在进行),IPLocation还未被赋值,所以输出undefined。
  • 而start函数内部,await getData(path)会等待异步操作完成,拿到数据后才给IPLocation赋值,之后再打印,因此能正常输出。

另外提个细节:getData里的await JSON.parse(JSON.stringify(scrampled))是多余的,JSON.parse是同步操作,不需要加await;而且data.json()已经把响应解析成JSON对象了,这里的JSON.parse(JSON.stringify(scrampled))只是做了一次深拷贝,完全没必要用await。

解决办法

要在IPLocation赋值完成后再打印,有两种常用方式:

方式一:用立即执行异步函数包裹调用

let latitude, longitude, IPLocation;
// 用异步立即执行函数包裹,等待start执行完成
(async () => {
  await start(path);
  console.log(IPLocation); // 正常输出
})();

async function start(path) {
  IPLocation = await getData(path);
  latitude = IPLocation.location.lat;
  longitude = IPLocation.location.lng;
  console.log(IPLocation);
}

async function getData(path) {
  const data = await fetch(path);
  const scrampled = await data.json();
  const parsed = JSON.parse(JSON.stringify(scrampled)); // 去掉多余的await
  return parsed;
}

方式二:用Promise的then方法

let latitude, longitude, IPLocation;
start(path).then(() => {
  console.log(IPLocation); // 正常输出
});

async function start(path) {
  IPLocation = await getData(path);
  latitude = IPLocation.location.lat;
  longitude = IPLocation.location.lng;
  console.log(IPLocation);
}

async function getData(path) {
  const data = await fetch(path);
  const scrampled = await data.json();
  const parsed = JSON.parse(JSON.stringify(scrampled)); // 去掉多余的await
  return parsed;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 06:45:34