AJAX回调超3秒未触发show_please_wait函数,求问题排查
问题原因分析
你的代码中show_please_wait()始终无法执行的核心问题是JavaScript的单线程事件循环机制,结合代码逻辑的细节问题导致:
同步
process函数阻塞事件循环
当AJAX请求完成触发onload回调后,代码会同步执行process(JSON.parse(request.responseText))。如果process函数耗时超过3秒,这段时间内主线程会被完全阻塞——定时器的回调即使到了触发时间,也必须等待process执行完毕、onload后续代码(设置is_processing = false、清除定时器)全部执行完才能运行。此时is_processing已经被设为false,所以show_please_wait()的条件永远不满足。
如果process耗时不足3秒,定时器还没触发就被clearTimeout取消,同样不会执行提示逻辑。is_processing时机设置不准确(可选)
如果你希望监控的是回调处理(process函数)的时长而非网络请求+处理的总时长,那么在request.send()时就设置is_processing = true是不合理的——这段时间包含了网络请求耗时,并非真正的处理耗时。
修复方案
根据你的需求(回调处理时长超3秒显示提示),调整代码如下:
var process_timer, is_processing = false; var request = createCORSRequest(); if (request) { request.onload = function() { var responseData = JSON.parse(request.responseText); // 开始处理前启动定时器,仅监控process的执行时长 is_processing = true; process_timer = setTimeout(function() { if (is_processing) { show_please_wait(); } }, 3000); // 异步执行process,避免阻塞主线程,让定时器回调有机会触发 setTimeout(function() { try { process(responseData); } finally { // 无论处理成功/失败,都重置状态 is_processing = false; clearTimeout(process_timer); hide_please_wait(); } }, 0); }; request.send(); }
如果你的需求是网络请求+处理总时长超3秒显示提示,可调整为:
var process_timer, is_processing = false; var request = createCORSRequest(); if (request) { // 发送请求时启动定时器,监控总时长 process_timer = setTimeout(function(){ if (is_processing) { show_please_wait(); } }, 3000); request.onload = function() { var responseData = JSON.parse(request.responseText); // 异步执行process,避免阻塞定时器回调 setTimeout(function() { try { process(responseData); } finally { is_processing = false; clearTimeout(process_timer); hide_please_wait(); } }, 0); }; is_processing = true; request.send(); }
内容的提问来源于stack exchange,提问作者Congregator
相关产品推荐
相关产品推荐

