如何在jQuery循环下一次执行前添加延迟?需等待$.post请求完成
解决方案:异步逐个处理请求,替代同步循环
当然可以!问题出在你用的$.each是同步遍历——它会一次性把所有$.post请求都发送出去,而不是等上一个请求完成再处理下一个,这不仅会导致加载器无法正常显示,还可能因为并发请求过多出现问题。
正确的做法是用递归函数来逐个处理选中的项,确保上一个请求完成后再启动下一个,这样既能保证顺序执行,又能让每行的加载器正常显示。
修改后的代码示例
// 先获取所有选中的元素,转成数组方便按索引处理 const checkedItems = $(".ids:checked").toArray(); let currentItemIndex = 0; const totalItems = checkedItems.length; // 定义递归处理函数 function processNextItem() { // 终止条件:所有项都处理完了就退出 if (currentItemIndex >= totalItems) { // 这里可以添加所有请求完成后的收尾逻辑,比如重置状态 return; } // 获取当前要处理的项 const $currentItem = $(checkedItems[currentItemIndex]); const itemId = $currentItem.val(); // 判断是否是最后一个请求 const last_request = (currentItemIndex === totalItems - 1) ? 1 : 0; // 显示当前行的加载器(这里替换成你实际的加载器代码) $(`td#Id_${itemId}`).html('<span class="loader">处理中...</span>'); $(".modal_close_btn").hide(); // 发送异步请求 $.post("db/delete_test.php", { Id: itemId, last_request: last_request }, function(data) { // 请求成功后更新当前行的内容 $(`td#Id_${itemId}`).html(data.message); // 如果是最后一个请求,执行对应的收尾操作 if (currentItemIndex === totalItems - 1) { $(".modal_close_btn").show(); // 这里可以添加其他最后请求的逻辑,比如提示全部完成 } // 处理完当前项,索引+1,递归调用处理下一个 currentItemIndex++; processNextItem(); }) .fail(function() { // 处理请求失败的情况,避免一个失败导致全部卡住 $(`td#Id_${itemId}`).html('处理失败'); // 继续处理下一个项(如果不需要继续,可以去掉这两行) currentItemIndex++; processNextItem(); }); } // 启动第一个请求的处理 processNextItem();
关键说明
- 递归替代同步循环:通过递归函数
processNextItem,每次只处理一个项,只有当前请求完成(成功或失败)后,才会启动下一个请求,完美解决了顺序执行的需求。 - 加载器正常显示:因为每次处理单个请求,在发送请求前可以先渲染加载器,请求完成后再替换成结果,浏览器有足够时间渲染加载器,不会被同步操作阻塞。
- 错误处理:添加了
.fail回调,即使某个请求失败,也不会中断后续项的处理(如果需要中断,可以在fail里不调用processNextItem)。
内容的提问来源于stack exchange,提问作者Boy
相关产品推荐
相关产品推荐

