面向对象模式下如何在类外监听AJAX请求完成状态?
解决AJAX请求外部控制加载遮罩的问题
兄弟,你原来写的while循环思路有个致命问题——JavaScript是单线程的,这个循环会死死霸占主线程,导致AJAX的success回调根本没机会执行,遮罩会永远挂在页面上,根本到不了移除那一步。
给你两个靠谱的解决方案,都是在外部控制遮罩的显示和移除:
方案一:改造myClass,暴露Promise供外部监听
这个方案最精准,只针对当前实例的AJAX请求,不会受其他请求影响:
function myClass() { // 把AJAX请求包装成Promise,挂载到实例上 this.ajaxPromise = new Promise((resolve) => { $.ajax({ type:'get', url:'some/path/', success:function(response) { // 原来的逻辑:设置标记等操作 resolve(response); // 标记请求完成 }, error: function() { resolve(); // 即使请求失败,也标记完成,避免遮罩一直挂着 } }); }); return this; } // 外部使用流程 var obj = new myClass(); // 显示遮罩 jQuery('body').append('<div id="overlay"></div>'); // 监听请求完成,移除遮罩 obj.ajaxPromise.then(() => { jQuery('#overlay').remove(); });
方案二:不修改myClass,用jQuery全局AJAX事件监听
如果不想动myClass的内部代码,可以用jQuery的全局AJAX事件,但要注意过滤目标请求,避免影响页面上的其他AJAX:
var obj = new myClass(); // 显示遮罩 jQuery('body').append('<div id="overlay"></div>'); // 监听全局AJAX完成事件 jQuery(document).ajaxComplete(function(event, xhr, settings) { // 只处理我们目标URL的请求 if (settings.url === 'some/path/') { jQuery('#overlay').remove(); // 解绑事件,避免触发后续其他AJAX时重复执行 jQuery(this).off('ajaxComplete'); } });
⚠️ 注意:千万别想着把AJAX改成同步(async: false),同步请求会直接冻结浏览器,用户体验极差,而且现在很多浏览器在某些场景下已经禁止同步AJAX了。
内容的提问来源于stack exchange,提问作者asprin
相关产品推荐
相关产品推荐

