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

JavaScript fetch异步请求修改的全局变量为何外部无法获取更新值

原因说明

你的全局变量实际上已经被成功更新,只是你打印变量的时机早于fetch回调的执行时机。
fetch属于异步非阻塞API,JS主线程调用fetch后,不会等待HTTP请求返回结果,会直接向下执行后续的同步代码(也就是你写的三个console.log),这时候then内的回调函数还没有被触发,所以你打印的还是变量的初始值。等HTTP请求完成后,才会执行then回调修改全局变量,此时你再访问这几个变量就能拿到更新后的值。
普通同步函数是执行完全部逻辑才会继续执行后面的代码,所以修改全局变量后可以立即拿到新值,异步函数的执行时机和主线程同步代码是错开的,就出现了你遇到的现象。

解决方案

方案1:将依赖请求结果的逻辑放入回调中

所有需要用到fetch返回数据的逻辑,都放在then回调内部执行,确保执行时数据已经返回:

var arr = [];
var dat=[1,2];
var prova = 5;
fetch('https://ipinfo.io')
  .then(function(response) {
    return response.text();
  }).then(function(text) {
  arr.push(text);
  dat = arr;
  prova=prova+1;
  // 所有依赖这三个变量的逻辑都写在这里
  console.log(arr);
  console.log(dat);
  console.log(prova);
  document.getElementById('pText').innerHTML = dat[0];
});

方案2:使用async/await语法简化异步逻辑

async/await是Promise的语法糖,可以让异步代码的写法更接近同步代码,可读性更高:

async function getIpInfo() {
  var arr = [];
  var dat=[1,2];
  var prova = 5;
  // 等待请求返回再执行后续代码
  const response = await fetch('https://ipinfo.io');
  const text = await response.text();
  arr.push(text);
  dat = arr;
  prova=prova+1;
  // 后续可以直接使用更新后的变量
  console.log(arr);
  console.log(dat);
  console.log(prova);
  document.getElementById('pText').innerHTML = dat[0];
  // 可以把结果返回供外部使用
  return { arr, dat, prova };
}

// 调用异步函数,可通过then拿到返回结果
getIpInfo().then(result => {
  console.log('外部拿到的请求结果:', result);
})

如果你确实需要把请求结果存为全局变量供其他模块调用,要确保其他模块访问这个变量的时机晚于fetch请求完成的时间,否则还是会拿到初始值。你可以通过增加请求完成状态标记、订阅回调等方式判断时机。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:54:03