XMLHttpRequest异步执行引发按钮禁用状态异常的问题咨询
问题解答:为何XMLHttpRequest未完成时代码仍继续执行?
核心原因:异步执行机制
你的问题完全和同步/异步函数有关。当你调用update()时,里面的XMLHttpRequest默认是异步模式(open第三个参数true),浏览器发送请求后不会等待请求完成,而是直接继续执行update()后面的代码——也就是立刻把按钮重新启用,所以你看不到按钮禁用的状态,控制台也会马上输出两个日志,直到数秒后请求完成才更新页面内容。
哪怕你把open的第三个参数改成false(同步模式),也可能因为浏览器的主线程阻塞限制,或者代码逻辑问题没达到预期效果,而且同步请求会导致页面卡死,完全不推荐使用。
代码修复方案
要实现“点击后禁用按钮,请求完成后再启用”的效果,必须把启用按钮的代码放到请求完成的回调函数里,只有当确认请求成功完成后,才恢复按钮状态。
修改后的代码如下:
点击事件代码调整:
global_button = document.createElement("button"); global_button.innerHTML = "UPDATE"; global_button.id = "update"; global_button.disabled = false; document.body.appendChild(global_button); document.getElementsByClassName("two")[0].append(global_button); global_button.addEventListener("click", function () { console.log("After CLICKED"); global_button.disabled = true; // 点击后立即禁用按钮 update(function() { // 请求完成后执行的回调 global_button.disabled = false; console.log("AFTER FUNCTION RETURN VALUES"); }); });
update函数调整:
var xmlhttp; function loadFile(file, successFunc){ xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200){ document.getElementById("content").innerHTML = xmlhttp.responseText; successFunc(); // 请求成功后调用传入的回调函数 } }; xmlhttp.open("GET", file, true); xmlhttp.send(); } function update(callback){ loadFile("update.php", callback); }
关键说明
- 异步请求的核心逻辑是:发送请求后,浏览器在后台处理请求,当请求状态变化时(比如完成),再触发
onreadystatechange回调函数。所以所有需要等待请求完成的操作,都必须放在这个回调里。 - 永远不要用同步请求(
open第三个参数false),它会阻塞整个页面的交互,用户体验极差,甚至可能被浏览器限制。
内容的提问来源于stack exchange,提问作者BedSon
相关产品推荐
相关产品推荐

