调用ASP.NET母版页中声明为变量的AJAX函数执行时序问题求解
问题根因
你遇到的执行顺序问题和ASP.NET母版页、子页面的加载逻辑无关,核心问题是你定义的setISCSession函数没有返回AJAX请求对应的Promise对象:$.when()需要接收可等待的Promise实例来判断异步任务是否完成,当函数没有返回值时,$.when()会直接判定任务执行完毕,立即触发后续的.done()逻辑,自然会出现AJAX请求还没完成、sessionStorage还没赋值就先执行取值操作的问题。
解决方法
只需要修改公共函数返回Promise,同时保证公共函数的加载顺序早于子页面业务代码即可,完全保留跨页面调用的能力。
1. 修改公共函数(母版页/单独公共JS中)
给setISCSession加上返回值,返回$.ajax生成的Promise实例:
// 挂在window上全局暴露,所有子页面可直接调用 window.setISCSession = function(isc) { // 新增return 返回AJAX的Promise return $.ajax({ type: "POST", dataType: "json", contentType: "application/json; charset=utf-8", url: "/WebService/idc.asmx/SetISCSessionVars", cache: false, data: JSON.stringify({ ISC: isc }), }).done(function (result) { if (!result || result.d === "" || result.d.length == 0) { // 可补充空结果处理逻辑 } else { var iscData = JSON.parse(result.d)[0]; const siteTZ = iscData.SITE_TZ; const utcOffset = iscData.UTC_OFFSET; $.session.set('Site_TZ', siteTZ); $.session.set('UTC_Offset', utcOffset); // 其他赋值逻辑 } }).fail(function (jqXHR, textStatus, errorThrown) { alert(textStatus + ' - ' + errorThrown + '\n' + jqXHR.responseText); }); }
2. 子页面调用代码调整(可选优化)
修改后原代码可以正常运行,也可以去掉不必要的$.when包裹,简化写法:
$(document).on('change', '#ddlSelISC', function () { const isc = $(this).val(); // 直接调用异步函数,等待请求完成后执行后续逻辑 setISCSession(isc).done(function () { const tz = $.session.get('Site_TZ'); $('#hfSiteTZ').val(tz); $('#lblOffset').text($.session.get('UTC_Offset')); // 其他业务逻辑 }); });
额外注意事项
- 为了避免全局变量污染,也可以自定义全局命名空间挂载公共方法,示例:
// 公共JS中定义命名空间 window.MySiteUtils = window.MySiteUtils || {}; MySiteUtils.setISCSession = function(isc) { /* 函数逻辑 */ } // 子页面调用 MySiteUtils.setISCSession(isc).done(/* 后续逻辑 */) - 如果担心函数未定义的问题,只需要在母版页的
<head>区域优先引入公共JS文件,子页面的业务JS放在公共JS之后加载即可。
内容的提问来源于stack exchange,提问作者NoBullMan
相关产品推荐
相关产品推荐

