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

调用带await的async异步函数后全局变量赋值不生效是什么原因?

问题核心原因

你遇到的问题不属于作用域问题,本质是异步代码的执行时序不符合你的预期。

所有async标记的函数,只要在内部碰到await关键字,会立刻暂停当前函数的执行,让出主线程执行后续的同步代码,直到await等待的异步操作完成后,才会回到async函数内部继续执行剩余代码。

你的代码实际执行顺序是:

  1. 全局初始化seasonStart、seasonID为空字符串
  2. 调用getCurrentSeasonapi(getCurrentSeasonURL),函数运行到const response = await fetch(url);时,因为fetch是异步网络请求,所以直接暂停getCurrentSeasonapi的执行,回到主线程继续执行后续代码
  3. 直接运行console.log(seasonStart);,此时请求还未返回,setSeasonInfo根本没执行,变量还是初始空值
  4. 等主线程所有同步代码执行完毕,且fetch请求拿到返回结果后,才会回到getCurrentSeasonapi继续执行剩余逻辑,解析JSON、调用setSeasonInfo给全局变量赋值,所以setSeasonInfo内部的打印能输出正确值。

为什么你的测试用例表现不同

你写的测试用例里的async函数内部没有await任何异步操作,会直接同步执行完成,所以调用changeTest()后会立刻把test改成100,后续代码当然能拿到修改后的值。如果给测试用例加个异步等待逻辑,就能复现你实际遇到的问题:

var test = 1;
async function changeTest() {
    // 增加100ms延迟模拟网络请求
    await new Promise(resolve => setTimeout(resolve, 100))
    test = 100;
}
document.getElementById("first").innerHTML = test + `<br>` + 'Run Function:' + `<br>`;
changeTest();
// 这里输出还是1,和你实际场景的空字符串表现一致
document.getElementById("first").innerHTML += test

修复方案

如果要保证打印时变量已经被赋值,需要等待异步函数执行完成再运行后续逻辑,两种常用实现方式:

  1. 用await等待异步函数执行完成(注意await只能在async函数内部使用,可以用自执行async函数包裹):
(async () => {
  await getCurrentSeasonapi(getCurrentSeasonURL);
  console.log(seasonStart);
})()
  1. 用Promise.then添加回调,异步函数执行完成后自动触发回调:
getCurrentSeasonapi(getCurrentSeasonURL).then(() => {
  console.log(seasonStart);
})

内容的提问来源于stack exchange,提问作者J.Doe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 06:15:05