在我的页面javascript文件中,我想在所有XHR返回后执行一些脚本。我知道通过jquery对XHR请求有ajaxStop()
,但由于我使用的是Mithril并且它有自己的Ajax包装器,我实际上不能使用ajaxStop()
。
我也尝试过其他一些解决方案,比如
function isAllXhrComplete(){
window.activeAjaxCount--;
if (window.activeAjaxCount === 0){
//execute something here.
}
}
(function(open) {
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
this.addEventListener("load", isAllXhrComplete());
open.call(this, method, url, async, user, pass);
};
})(XMLHttpRequest.prototype.open);
(function(send) {
XMLHttpRequest.prototype.send = function (data) {
window.activeAjaxCount++;
send.call(this, data);
};
})(XMLHttpRequest.prototype.send);
但似乎由于所有XHR调用都是单独触发的,window.activeAjaxCount
总是为1或0,因此会在每个完成的XHR请求中触发脚本执行。
是否有任何好方法可以等待所有XHR请求返回?
答案 0 :(得分:2)
你的错误在这里:
this.addEventListener("load", isAllXhrComplete());
isAllXhrComplete
未作为回调传递,因为您立即调用它。而是传递isAllXhrComplete()
调用的结果。
你必须写:
this.addEventListener("load", isAllXhrComplete);
除此之外,在包装现有函数时应该非常小心。一个正确的方法是:
(function(send) {
XMLHttpRequest.prototype.send = function () {
window.activeAjaxCount++;
return send.apply(this, arguments);
};
})(XMLHttpRequest.prototype.send);
重要的是你return
原始函数的结果,并使用apply
传递所有可能的参数。否则,如果更改了这些函数的签名,您将来可能会破坏代码。
您需要对open
包装器执行相同的操作:
(function(open) {
XMLHttpRequest.prototype.open = function() {
this.addEventListener("load", isAllXhrComplete);
return open.apply(this, arguments);
};
})(XMLHttpRequest.prototype.open);