AJAX请求执行时JavaScript轮询函数的合理调用位置
解决AJAX提交与实时轮询同步的问题
你的问题核心在于轮询启动时机太晚——你现在是在提交请求成功后才开始轮询,这时候后端已经处理完所有进度,自然直接显示100%了。正确的做法是:在发起提交AJAX请求的同时,立刻启动轮询,不需要等提交请求完成。
具体修改步骤:
- 把启动轮询的
setTimeout(letsPoll, interval)从success回调里移出来,放在提交AJAX请求的代码之后,确保提交请求一开始就同步启动轮询。 - 修复轮询的循环逻辑:当前
letsPoll只执行一次AJAX就结束,需要在每次轮询完成且进度未到100%时,继续设置下一次轮询,保证持续获取实时数据。 - 修正
clearTimeout的错误:你用clearTimeout(interval)是无效的,需要用变量保存轮询的定时器ID,才能正确终止轮询。
修改后的完整代码如下:
$(document).ready(function() { var interval = 2000; var pollTimeout; // 保存轮询定时器ID,用于后续终止轮询 $(document).on('click', '#submit-catalog', function() { $('#submit-catalog').prop("disabled", true); var url = [[@{'/admin/catalog/activate'}]]; // 发起提交请求 var xhr = $.ajax({ url: url, complete: function(data) { // 这里可以处理提交请求完成后的通用逻辑(不管成功失败) } }); // 立刻启动轮询,无需等待提交请求完成 setTimeout(letsPoll, interval); }); function letsPoll() { $('#progress-bar').show(); $.ajax({ type: 'GET', url: [[@{'/admin/catalog/getPercentageCompletion'}]], success: function(data) { $('.progress-text').text(data + '%'); $('#upload-progress').css('width', data + '%'); if (data == 100) { clearTimeout(pollTimeout); // 用保存的ID终止轮询 aqShowInfoToast("All hosted catalogs has been Activated"); $('#submit-catalog').prop("disabled", false); aqCloseModal(); return; // 终止后续逻辑,避免重复设置轮询 } // 进度未完成,继续设置下一次轮询 pollTimeout = setTimeout(letsPoll, interval); }, error: function() { // 轮询失败时也重试,避免意外中断 pollTimeout = setTimeout(letsPoll, interval); } }); } });
关键说明:
- 轮询启动时机:提交请求发起后立刻启动,确保后端开始处理进度时,前端能同步获取实时数据。
- 循环轮询逻辑:每次轮询成功且进度未到100%时,重新设置定时器,保证轮询持续进行。
- 定时器ID管理:用
pollTimeout变量保存每次的定时器ID,确保进度完成时能正确终止轮询,避免无效请求。
内容的提问来源于stack exchange,提问作者nirmesh
相关产品推荐
相关产品推荐

