如何让JavaScript异步请求回调完成后再执行后续脚本?
解决异步请求执行顺序问题
你的问题根源在于loadWordlist里使用了异步XMLHttpRequest(open方法第三个参数为true)——浏览器会在后台发送请求,同时继续执行后续代码,导致body中的secondFunction先于请求完成后的firstFunction输出。
以下是几种可行的解决方案:
方法1:使用回调函数
给loadWordlist添加回调参数,在请求成功完成后触发回调,将secondFunction的逻辑放入回调中:
<html> <head> <script> function main(callback){ function loadWordlist(url, cb){ var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { console.log('firstFunction'); // 请求完成后执行传入的回调 cb(); } }; xhttp.open("GET", url, true); xhttp.send(); } loadWordlist('https://www.example.com/', callback); } // 传入secondFunction的逻辑作为回调 main(function() { console.log('secondFunction'); }); </script> </head> <body> </body> </html>
方法2:使用Promise封装(现代写法)
将异步请求封装为Promise,通过.then()链式调用控制执行顺序:
<html> <head> <script> function main(){ function loadWordlist(url){ return new Promise((resolve, reject) => { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4) { if(this.status == 200) { console.log('firstFunction'); resolve(); } else { reject(new Error('请求失败')); } } }; xhttp.open("GET", url, true); xhttp.send(); }); } // 等待请求完成后执行secondFunction loadWordlist('https://www.example.com/').then(() => { console.log('secondFunction'); }).catch(err => { console.error(err); }); } main() </script> </head> <body> </body> </html>
如果习惯更直观的同步写法,可以用async/await:
<html> <head> <script> async function main(){ function loadWordlist(url){ return new Promise((resolve, reject) => { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4) { if(this.status == 200) { console.log('firstFunction'); resolve(); } else { reject(new Error('请求失败')); } } }; xhttp.open("GET", url, true); xhttp.send(); }); } // 等待请求完成 await loadWordlist('https://www.example.com/'); console.log('secondFunction'); } main() </script> </head> <body> </body> </html>
注意:不要将XMLHttpRequest改为同步模式(
open第三个参数设为false),这会阻塞浏览器UI线程,导致页面在请求完成前完全卡顿,严重影响用户体验。
内容的提问来源于stack exchange,提问作者Notme
相关产品推荐
相关产品推荐

