短时间多次调用原生XMLHttpRequest,结果是否准确且互不干扰?
短时间多次调用原生XMLHttpRequest的问题分析与修复
问题结论
你当前的原生JS代码无法保证responseText始终正确,且会干扰之前未完成的请求,核心问题出在变量作用域上。
原因解析
你代码里的xhrRequest_stat没有用var/let/const声明,属于全局变量。每次调用doStats时,这个变量都会被重新赋值为新的XMLHttpRequest实例——如果前一次请求还没完成,它的onreadystatechange回调里引用的xhrRequest_stat已经变成了新请求的实例,当旧请求最终完成时,你拿到的会是新请求的响应内容,完全混乱。
而之前用jQuery的$.ajax能正常运行,是因为jQuery内部会为每个请求创建独立的XHR对象,并且通过闭包绑定了对应请求的回调上下文,不会出现全局变量覆盖的问题。
修复方案
将xhrRequest_stat声明为函数内部的局部变量,确保每次调用doStats都生成独立的XHR实例,互不干扰:
function doStats(){ let params = ...; // 你的参数处理逻辑 let url = ...; // 目标请求地址 // 用const/let声明局部变量,隔离每次调用的作用域 const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (this.readyState === 4) { // 用this访问当前请求的实例,确保拿到对应请求的响应 console.log(this.responseText); } }; xhr.onerror = function(e) { console.log('Error getStats: ' + e); }; xhr.open('POST', url); xhr.setRequestHeader("Content-Type", 'application/x-www-form-urlencoded'); xhr.send(params); }
关键修改说明
- 用
const(或let)声明XHR变量,将其限制在doStats的函数作用域内,每次调用都会创建全新的变量和XHR实例,不会覆盖之前的请求实例。 - 回调里用
this访问当前请求的XHR实例(也可以直接用局部变量xhr),确保拿到的是当前请求的响应内容,不会被后续请求干扰。
修改后,无论你以何种频率和时机调用doStats,每个请求的响应都能正确对应,不会出现混乱。
内容的提问来源于stack exchange,提问作者Toniq
相关产品推荐
相关产品推荐

