JavaScript重复声明同名XMLHttpRequest 如何让两个请求逻辑正常运行
问题根因
这个现象的本质是变量引用覆盖叠加XHR异步特性共同导致的:
- 用
var声明的变量不具备块级作用域,在同一个window.onload的函数作用域内,先后两次var oReq = new XMLHttpRequest(),本质是对同一个变量的重复赋值,第一次赋值的第一个XHR实例引用,会被第二次赋值的第二个XHR实例直接覆盖。 - XHR的请求响应是异步的:同步代码会在极短时间内执行完两个XHR的初始化、open、send操作,但两个请求的回调会在网络请求完成后才异步触发。等第一个请求的回调触发时,外层作用域里的
oReq早就已经被替换成第二个XHR实例了,这时候回调里如果通过oReq读取响应数据,拿到的是还处于请求中、responseText为空的第二个实例,直接执行JSON.parse('')就会抛错,整个第一部分的渲染逻辑直接中断,最终表现为第8行开始的第一块代码完全失效,只有第二块代码能正常跑。
调整操作
- 彻底取消对
oReq同名变量的复用,把两个XHR实例改成独立的、带块级作用域的声明(用const/let,不要用var),比如把日统计请求的实例命名为gunlukReq,周统计的命名为haftalikReq,从根源上切断两个请求之间的引用关联。 - 每个XHR实例的回调逻辑里,全部通过自身的实例变量读取响应内容,不要依赖外层的公共变量取响应,避免后续改动引发的逻辑错乱。
- 给每个XHR加上
onerror监听,避免单个请求接口报错时,抛出的异常中断整个脚本的执行,连带影响另一个请求的渲染逻辑。
调整后的核心代码示例
window.onload = function() { // 原有逻辑:执行导入的校验方法 girisKontrolSaha(); // 日统计请求 独立实例 const gunlukReq = new XMLHttpRequest(); gunlukReq.open('GET', 'istatistik-günlük.php'); gunlukReq.onload = () => { if (gunlukReq.status !== 200) return; const data = JSON.parse(gunlukReq.responseText); // 原有渲染 table-orta1 的逻辑 }; gunlukReq.onerror = () => console.error('日统计接口请求失败'); gunlukReq.send(); // 周统计请求 独立实例 const haftalikReq = new XMLHttpRequest(); haftalikReq.open('GET', 'istatistik-haftalik.php'); haftalikReq.onload = () => { if (haftalikReq.status !== 200) return; const data = JSON.parse(haftalikReq.responseText); // 原有渲染 table-orta2 的逻辑 }; haftalikReq.onerror = () => console.error('周统计接口请求失败'); haftalikReq.send(); }
注意:如果一定要复用同一个变量名承载XHR实例,必须等第一个实例的整个请求、响应、渲染流程完全执行完成之后,再重新给变量赋值新的XHR对象,绝对不能在同步代码段里连续对同名变量赋值新的XHR实例。
内容的提问来源于stack exchange,提问作者Alp Güçer
相关产品推荐
相关产品推荐

