JavaScript回调函数异步执行疑问:XMLHttpRequest请求回调提前调用导致无响应输出
JavaScript回调函数异步执行疑问:XMLHttpRequest请求回调提前调用导致无响应输出
嘿,我完全懂你现在的困惑!你对回调函数的核心思路理解是对的——回调确实是用来保证依赖代码在前置操作完成后再执行,但这里你踩了XMLHttpRequest异步特性的坑啦。
你当前的代码里,requestFunc在调用request.send()之后立刻执行了callBackFunc(request.response),但问题就出在send()这个操作是异步非阻塞的:send()只是把网络请求发出去,浏览器会在后台单独处理这个请求,而JavaScript主线程不会停下来等请求完成,会直接往下执行你的回调函数。这时候请求还在传输中,根本没拿到服务器的响应,request.response自然是空的,所以printFunc输出啥也没有。
要解决这个问题,你需要借助XMLHttpRequest的事件监听,在请求真正完成、拿到响应的时机再调用回调函数,给你两种常用的实现方式:
方式一:监听
load事件(推荐,更直观)
当请求成功完成并拿到响应时,load事件会被触发,这时候再执行回调:function requestFunc(callBackFunc){ const request = new XMLHttpRequest(); request.open("GET", "https://somewebsite.com"); // 绑定load事件,请求成功完成时触发 request.addEventListener('load', function() { // 这里的this指向当前的XMLHttpRequest实例,this.response就是服务器返回的内容 callBackFunc(this.response); }); request.send(); } function printFunc(response){ console.log(response); } // 直接传递printFunc即可,无需额外嵌套箭头函数 requestFunc(printFunc);方式二:监听
readystatechange事件(更底层,能监听请求的所有状态变化)
XMLHttpRequest有不同的readyState状态,当readyState === 4且status === 200时,说明请求已完成且成功:function requestFunc(callBackFunc){ const request = new XMLHttpRequest(); request.open("GET", "https://somewebsite.com"); request.addEventListener('readystatechange', function() { // 检查请求是否完成且响应状态正常 if (this.readyState === 4 && this.status === 200) { callBackFunc(this.response); } }); request.send(); } function printFunc(response){ console.log(response); } requestFunc(printFunc);
总结一下:回调函数本身不会自动帮你处理异步等待,你得自己找到异步操作完成的“正确时机”,再去触发回调——对于网络请求来说,就是对应的完成事件触发的时候,而不是调用send()之后立刻执行。
内容来源于stack exchange
相关产品推荐
相关产品推荐

