延迟Ajax调用获取购物车总数代码不生效如何解决
代码存在的问题
你写的实现一共有3个核心错误,完全无法匹配业务诉求:
this指向丢失:setTimeout传入的普通函数运行时,上下文默认指向全局window对象(严格模式下为undefined),根本不是外层的XMLHttpRequest实例,所以this.responseText永远拿不到正确的返回值,会直接报错。- 延迟逻辑位置错误:你的业务需求是「等其他依赖脚本执行完成后,再发起Ajax请求拿购物车总数」,但当前代码是点击后立刻发起Ajax请求,只是等请求返回后再延迟500毫秒更新DOM,逻辑完全和需求相反;而且固定写死500毫秒延迟非常不可靠——如果依赖脚本执行时间超过500毫秒还是会出问题,执行时间远小于500毫秒又会让用户看到不必要的加载等待。
- 缺少Ajax状态校验:
onreadystatechange事件会在请求的每个生命周期阶段触发(一共会触发4次),你没有判断readyState === 4(请求完成)和HTTP状态码为200的成功条件,会在请求还没返回结果的时候就执行后续逻辑,触发空值错误。
修正方案
优先监听依赖脚本执行完成的对应事件触发请求,如果实在没有对应事件可以监听,再把延迟逻辑放到发起Ajax之前,同时修正this指向、增加状态校验:
document.addEventListener("click", cartItemTotal); function cartItemTotal() { // 延迟放在发起请求前,等依赖逻辑跑完再发请求 setTimeout(function() { const xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { // 先判断请求是否成功完成 if (xhttp.readyState === 4 && xhttp.status === 200) { document.getElementById("UpdateCartCount").innerHTML = xhttp.responseText; } } xhttp.open("POST", "items.php"); xhttp.send(); }, 500); }
更优实践是不要用固定setTimeout做依赖等待:如果其他依赖脚本有执行完成的回调、自定义事件或者Promise状态,直接在依赖逻辑执行完成的时机触发购物车请求,比固定延时可靠得多,不会出现时长不够或者无意义等待的问题。
内容的提问来源于stack exchange,提问作者jononstein
相关产品推荐
相关产品推荐

