解决批量审批按钮的竞态条件问题与请求延迟过长问题
解决办法
1. 串行发起请求(无固定延迟,前一个完成再发下一个)
把单个审批的逻辑封装成返回Promise的函数,循环逐个执行——前一个请求成功后再发起下一个,既避免并发导致的服务器压力,又不用固定等待1.5秒,总耗时取决于服务器处理每个请求的实际时间,比固定延迟更高效。
代码示例:
// 封装单个审批的请求逻辑,返回Promise function approveItem($btn, note) { return new Promise((resolve, reject) => { $.ajax({ url: "/your-approval-api", // 替换为实际接口地址 method: "POST", data: { id: $btn.data("id"), // 从按钮获取审批ID,根据实际情况调整 note: note }, success: () => resolve(), error: (err) => reject(err) }); }); } // 一键审批的核心逻辑 async function batchApprove() { const $this = $(this); const approvalNote = "你的审批备注内容"; // 替换为实际备注 const $approvalBtns = $this.parents("li").find("ul button.approve"); // 逐个串行执行审批 for (let i = 0; i < $approvalBtns.length; i++) { const $btn = $($approvalBtns[i]); try { await approveItem($btn, approvalNote); // 可选:审批成功后更新UI,比如按钮置灰、标记已审批 $btn.prop("disabled", true).text("已审批"); } catch (err) { console.error(`第${i+1}项审批失败`, err); // 可选:遇到失败是否继续执行后续审批,取消注释则停止 // break; } } } // 给一键审批按钮绑定事件 $("#batch-approve-btn").on("click", batchApprove);
2. 控制并发数的批量请求(兼顾速度和服务器压力)
如果串行执行速度太慢,可以限制同时发起的请求数量(比如一次3-5个),等当前批次全部完成后再发起下一批,平衡处理速度和服务器负载。
代码示例:
function approveItem($btn, note) { return new Promise((resolve, reject) => { $.ajax({ url: "/your-approval-api", method: "POST", data: { id: $btn.data("id"), note: note }, success: () => resolve(), error: (err) => reject(err) }); }); } async function batchApprove() { const $this = $(this); const approvalNote = "你的审批备注内容"; const $approvalBtns = $this.parents("li").find("ul button.approve"); const concurrencyLimit = 3; // 同时发起3个请求,可根据服务器性能调整 let currentIndex = 0; // 单个并发任务的处理逻辑 async function processTask() { while (currentIndex < $approvalBtns.length) { const idx = currentIndex++; const $btn = $($approvalBtns[idx]); try { await approveItem($btn, approvalNote); $btn.prop("disabled", true).text("已审批"); } catch (err) { console.error(`第${idx+1}项审批失败`, err); } } } // 创建指定数量的并发任务并执行 const tasks = Array.from({ length: concurrencyLimit }, processTask); await Promise.all(tasks); } $("#batch-approve-btn").on("click", batchApprove);
3. 后端新增批量审批接口(最优解)
最彻底的解决方式是让后端开发一个批量审批接口,前端只需收集所有需要审批的ID和备注,一次性发送一个POST请求,由服务器批量处理。这样既消除了竞态问题,耗时也最短。
前端代码示例:
$("#batch-approve-btn").on("click", function() { const $this = $(this); const approvalNote = "你的审批备注内容"; const $approvalBtns = $this.parents("li").find("ul button.approve"); // 收集所有需要审批的ID const approvalIds = $approvalBtns.map(function() { return $(this).data("id"); }).get(); // 发送批量审批请求 $.ajax({ url: "/batch-approval-api", // 后端新增的批量接口地址 method: "POST", data: { ids: approvalIds, note: approvalNote }, success: (res) => { console.log("批量审批完成", res); // 批量成功后统一更新UI $approvalBtns.prop("disabled", true).text("已审批"); }, error: (err) => { console.error("批量审批失败", err); } }); });
内容的提问来源于stack exchange,提问作者Coderio
相关产品推荐
相关产品推荐

