使用XMLHttpRequest读取JSON后无法存入全局变量:求原因与解决方法
为什么XMLHttpRequest的响应无法存入全局变量,最后console.log输出undefined?
问题核心在于异步代码的执行顺序:你开启的是异步XMLHttpRequest请求(open方法第三个参数为true),浏览器会在后台处理请求,同时继续执行后续代码,而不是等待请求完成。
具体执行流程:
- 先声明全局变量
myArr,初始值为undefined - 发送异步请求后,直接执行最后一行的
console.log(myArr),此时请求还未完成,myArr仍未被赋值 - 等请求成功返回后,才会触发
onreadystatechange回调,调用myFunction给myArr赋值,这时回调里的console.log才会输出正确值
解决方法
方法1:将使用全局变量的逻辑放在回调流程内
把所有需要用到myArr的代码,放在请求成功后的回调或其调用的函数中:
var xmlhttp = new XMLHttpRequest(); var url = './output.json'; var myArr; xmlhttp.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { let arr = JSON.parse(this.responseText); myFunction(arr); } }; xmlhttp.open('GET', url, true); xmlhttp.send(); function myFunction(arr) { myArr = arr; console.log(myArr); // 在这里编写所有需要使用myArr的代码 processMyArr(); } function processMyArr() { console.log("处理全局变量myArr:", myArr); }
方法2:用Promise封装请求,结合async/await实现"同步化"写法
将异步请求封装为Promise,再通过async/await让代码逻辑更直观:
function fetchJson(url) { return new Promise((resolve, reject) => { const xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function () { if (this.readyState == 4) { this.status == 200 ? resolve(JSON.parse(this.responseText)) : reject(new Error(`请求失败,状态码:${this.status}`)); } }; xmlhttp.open('GET', url, true); xmlhttp.send(); }); } async function init() { var myArr = await fetchJson('./output.json'); console.log(myArr); // 此处可直接使用myArr } init();
方法3:改用现代浏览器支持的fetch API
fetch是XMLHttpRequest的替代方案,语法更简洁,同样结合async/await使用:
async function init() { try { const response = await fetch('./output.json'); const myArr = await response.json(); console.log(myArr); // 在这里编写使用myArr的逻辑 } catch (error) { console.error('请求出错:', error); } } init();
内容的提问来源于stack exchange,提问作者Sunny Raj
相关产品推荐
相关产品推荐

