为何代码未等待所有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'), ''); });
额外排查要点
- 确认所有AJAX请求正常发起:打开浏览器开发者工具的网络面板,检查每个
UpdateWaferSplits请求是否都成功发送并收到响应。如果有请求失败,排查WID参数是否正确获取、服务端接口是否正常。 - 避免事件重复绑定:确保
hide.bs.dropdown事件只绑定了一次,防止多次触发导致逻辑混乱。
内容的提问来源于stack exchange,提问作者Mike Daneman
相关产品推荐
相关产品推荐

