如何在UploadMainData接口处理时每2秒调用progressChecking进度查询接口?
问题结论与修复方案
首先回答你的核心疑问:jQuery的AJAX请求async默认值就是true,你不需要额外给主上传接口配置该参数。你遇到的进度查询接口被阻塞、必须等上传接口完成才返回的问题,是两个错误导致的:
- 进度查询的AJAX参数拼写错误:你写的是
asyn: true,遗漏了字母c,错误的参数名不生效,导致进度查询请求变成同步阻塞模式。 - 后端存在会话阻塞逻辑:绝大多数服务端框架默认会对同一用户的会话请求加锁,前一个请求未处理完成时,同会话的后续请求会进入排队队列,必须等前一个请求结束才会被处理。
具体修复步骤
1. 修复前端代码
修正拼写错误,同时补充主上传接口异常场景的定时器清除逻辑,避免无效轮询:
// 全局变量存储定时器ID let myVar = null; $("#formInputUnggah").submit(function (e) { e.preventDefault(); $("#submitFile").html("<i class='fa fa-circle-o-notch fa-spin'></i> Load..").prop("disabled", true); $.ajax({ type: "POST", url: "${local_server}/ABCController/UploadMainData", data: new FormData(this), processData: false, contentType: false, cache: false, dataType: "json", success: function (e) { console.log(e); }, error: function () { // 上传请求异常时清除定时器 if(myVar) clearInterval(myVar); $("#submitFile").html("Unggah").prop("disabled", false); } }); // 启动轮询 myVar = setInterval(checkprog, 2000); }); function checkprog() { console.log("masuk"); $.ajax({ type: 'GET', async: true, // 修正拼写错误 url: '${local_server}/ABCController/progressChecking', dataType: 'json', success: function (response) { console.log(response); const elem = document.getElementById("myBar"); const result = (response.data.processed_data / response.data.total_data ) * 100 ; elem.style.width = result.toFixed(0) + "%"; elem.innerHTML = result.toFixed(0) + "%"; if(result==100){ clearInterval(myVar); $.confirm({ title : response.status, content : response.status, buttons : { ok : { isHidden : false, keys : [ 'y' ], action : function() { elem.style.width = "0%"; elem.innerHTML = ""; $("#formInputUnggah")[0].reset(); $("#submitFile").html("Unggah").prop("disabled", false); } } } }); }else if(response.status=="Error/Failed"){ clearInterval(myVar); elem.style.width = "0%"; elem.innerHTML = ""; $("#formInputUnggah")[0].reset(); $("#submitFile").html("Unggah").prop("disabled", false); } }, error: function () { // 进度查询异常时可根据需求选择是否清除定时器 } }); }
2. 后端适配修改
要彻底解决请求阻塞问题,需要对后端逻辑做调整:
- 提前释放会话锁:上传接口接收完文件、不需要再读写会话数据后,立即调用对应框架的会话释放方法(例如PHP的
session_write_close()),不要等整个文件处理逻辑执行完才释放会话锁,这样后续的进度查询请求就可以正常被处理。 - 异步处理文件逻辑:如果你的上传接口是同步执行文件解析、入库等全部业务逻辑才返回响应,需要调整为异步模式:接收文件后立即返回响应,后台异步执行文件处理逻辑,同时将处理进度写入Redis等全局缓存,进度查询接口直接读取缓存中的进度数据即可,不需要依赖会话。
内容的提问来源于stack exchange,提问作者Louis Sant
相关产品推荐
相关产品推荐

