在多函数内重定义全局变量tPrice遇阻:始终返回0,如何从JSON取值并设为全局?
问题分析与解决方案
嘿,我来帮你拆解下这个问题~你的tPrice始终返回0,并不是内层函数重定义了它,核心问题出在XMLHttpRequest的「异步特性」上:
当你执行那段代码时,JavaScript发送完AJAX请求后,不会傻等着请求返回结果,而是直接继续往下走。所以你后续去读取tPrice的时候,请求还没完成,它自然还是初始的0值。而内层函数里的tPrice = resp3.USD确实会修改变量,但这个操作要等到请求成功返回后才会执行,时间上比你读取它的动作晚很多。
另外关于全局变量的问题:如果tPrice本来就是在全局作用域(比如整个<script>最外层)声明的,那内层函数里的赋值操作确实会修改全局的tPrice——只是你得等请求完成后才能看到变化。
给你几个可行的解决办法
1. 把逻辑放到回调里(最直接的适配写法)
既然请求是异步的,那所有需要用到tPrice的代码,都得等请求完成后再执行,也就是放到onreadystatechange的回调函数里:
// 先在全局/外层作用域声明tPrice let tPrice = 0; if (tPrice == 0) { var xhr3 = new XMLHttpRequest(); xhr3.open("GET", "APICALL", true); xhr3.send(); xhr3.onreadystatechange = function() { // 别忘了加HTTP状态码检查,避免请求失败还继续处理 if (xhr3.readyState == 4 && xhr3.status === 200) { var resp3 = JSON.parse(xhr3.responseText); tPrice = resp3.USD; // 在这里写所有需要用到tPrice的逻辑 console.log("最新的价格:", tPrice); // 比如调用其他函数处理这个值 doSomethingWithPrice(tPrice); } } } function doSomethingWithPrice(price) { // 这里写你要用价格做的事情 }
2. 改用现代的异步写法(更清晰)
XMLHttpRequest是比较老旧的API,现在更推荐用fetch结合async/await,让异步代码看起来像同步的,可读性高很多:
let tPrice = 0; async function getPrice() { if (tPrice === 0) { try { // 等待请求返回 const response = await fetch("APICALL"); // 检查请求是否成功 if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } // 等待JSON解析完成 const resp3 = await response.json(); tPrice = resp3.USD; // 在这里使用tPrice console.log("更新后的价格:", tPrice); } catch (err) { console.error("获取价格出错了:", err); } } } // 调用这个函数触发请求 getPrice();
关于全局变量的小提醒
如果你一定要让tPrice是全局变量,记得不要在局部作用域里重新声明它(比如不要在函数里写let tPrice或者var tPrice),否则会创建一个局部变量,和全局的tPrice没关系了。只要在最外层声明一次,后面直接赋值就行。
内容的提问来源于stack exchange,提问作者Blynn
相关产品推荐
相关产品推荐

