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

为何代码未等待所有Promise完成就执行__doPostBack?

解决AJAX请求未完成就执行__doPostBack的问题

看起来你遇到的核心问题是原生Promise.all与jQuery Deferred对象的兼容性差异——虽然$.ajax返回的jqXHR对象支持then方法,但在部分场景下原生Promise无法正确追踪它的状态变化,导致__doPostBack提前执行。另外还有个潜在风险:如果任何一个AJAX请求失败,Promise.all会直接触发reject,而你的代码没有错误处理逻辑,这时候__doPostBack可能完全不执行。

下面给你两个针对性的解决方案:


方案一:使用jQuery原生$.when方法(推荐,更贴合你的技术栈)

既然所有AJAX请求都是通过jQuery发起的,直接用jQuery专门处理多异步任务的$.when方法是最稳妥的选择:

修改事件回调的最后一段代码:

// 替换原有的Promise.all代码
$.when.apply($, promises).done(function() {
    // 所有AJAX请求成功完成后执行回发
    __doPostBack($(event.target).attr('id'), '');
}).fail(function(xhr, status, error) {
    // 处理至少一个请求失败的情况(可选)
    console.error("更新Wafer Splits时出错:", error);
    // 如果即使请求失败也要执行回发,可以在这里调用__doPostBack
    // __doPostBack($(event.target).attr('id'), '');
});

为什么这能解决问题?

$.when是jQuery为Deferred对象设计的多任务等待方法,它会严格等待所有传入的Deferred都进入成功状态才触发done回调;如果有任何一个请求失败,会立刻触发fail回调。用apply($, promises)是因为$.when不直接支持数组参数,需要把数组展开为单个参数传入。


方案二:将jQuery AJAX包装为原生Promise

如果你更偏好原生Promise API,可以修改ExecuteServiceMethod函数,让它返回标准的原生Promise:

function ExecuteServiceMethod(page, fn, paramArray, successFn, errorFn) { 
    var paramList = ''; 
    if (paramArray.length > 0) { 
        for (var i = 0; i < paramArray.length; i += 2) { 
            if (paramList.length > 0) paramList += ','; 
            paramList += '"' + paramArray[i] + '":"' + paramArray[i + 1] + '"'; 
        } 
    } 
    paramList = '{' + paramList + '}'; 

    // 用原生Promise包裹jQuery AJAX请求
    return new Promise(function(resolve, reject) {
        $.ajax({ 
            type: "POST", 
            url: page + "/" + fn, 
            contentType: "application/json; charset=utf-8", 
            data: paramList, 
            dataType: "json", 
            success: function(response) {
                // 执行传入的成功回调(如果存在)
                if (successFn) successFn(response);
                // 标记Promise为成功状态
                resolve(response);
            }, 
            error: function(xhr, status, error) {
                // 执行传入的错误回调(如果存在)
                if (errorFn) errorFn(xhr, status, error);
                // 标记Promise为失败状态
                reject(error);
            } 
        });
    });
}

修改后你的原有Promise.all代码就能正常工作,记得加上错误处理:

Promise.all(promises).then(function () { 
    __doPostBack($(event.target).attr('id'), ''); 
}).catch(function(error) {
    console.error("至少一个请求失败:", error);
    // 可选:失败时是否执行回发
    // __doPostBack($(event.target).attr('id'), '');
});

额外排查要点

  1. 确认所有AJAX请求正常发起:打开浏览器开发者工具的网络面板,检查每个UpdateWaferSplits请求是否都成功发送并收到响应。如果有请求失败,排查WID参数是否正确获取、服务端接口是否正常。
  2. 避免事件重复绑定:确保hide.bs.dropdown事件只绑定了一次,防止多次触发导致逻辑混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:29:35