You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jQuery $.Deferred实现批量AJAX按顺序执行等待完成问题求助

问题原因

你当前的循环是同步遍历所有选中ID并直接触发doExport,所有AJAX请求会同时发起,才会出现先打印全部starting日志的情况。要实现串行执行,需要把每个操作通过Promise链式调用串联,保证前一个请求完成后再触发下一个。

代码修改方案

首先doExport函数可以简化(可选,因为$.ajax本身就返回DeferredPromise,不需要额外包装一层):

// 简化后的doExport
function doExport(id) {
  return $.ajax({
    type: "POST",
    url: "import.php",
    dataType: "json",
    data: { id: id }
  });
}

然后修改importInvoices的遍历逻辑,用reduce构建串行Promise链:

function importInvoices() {
  var checked = [];
  $('#apiCall').html("");

  // 收集选中ID
  $("input[name=selectedRow]:checked").each(function(num,row) {
    checked.push($(row).data('id'));
  });

  // 构建串行Promise链
  checked.reduce(function(prevPromise, currentId) {
    // 上一个请求完成后再执行下一个
    return prevPromise.then(function() {
      console.log("starting " + currentId);
      return doExport(currentId).then(function(result) {
        console.log("done " + currentId);
        $('#apiCall').html($("#apiCall").html() + result.messages);
      });
    });
  }, $.Deferred().resolve()) // 初始用已完成的Promise作为起点
  .then(function() {
    // 所有请求都完成后再隐藏加载提示
    $("#pleaseWaitContainer").hide();
  });
}

逻辑说明

  • reduce会把所有异步操作按顺序拼接成链式调用,每一步的执行都依赖上一步的完成
  • 初始传入已经resolve的Deferred对象,保证第一个请求可以正常触发
  • 原来同步执行的$("#pleaseWaitContainer").hide()移动到整个Promise链的最终回调中,避免请求还在执行就提前隐藏加载提示

修改后运行就能得到你预期的日志输出顺序,操作消息的展示顺序也能保证正确。

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 08:54:03