等待页面上的所有XHR在JavaScript中完成

等待页面上的所有XHR在JavaScript中完成,javascript,ajax,Javascript,Ajax,在我的页面javascript文件中,我希望在所有XHR返回后执行一些脚本。我知道对于通过jquery的XHR请求有ajaxStop(),但由于我使用的是Mithril,而且它有自己的Ajax包装器,所以我不能真正使用ajaxStop()。 我还尝试了其他一些解决方案,如 function isAllXhrComplete(){ window.activeAjaxCount--; if (window.activeAjaxCount === 0){ //execu

在我的页面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请求返回吗?

您的错误在这里:

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);
重要的是
返回原始函数的结果,并使用
apply
传递所有可能的参数。否则,如果这些函数的签名发生更改,将来可能会破坏代码

您需要对
open
包装器执行相同的操作:

(function(open) {
  XMLHttpRequest.prototype.open = function() {
    this.addEventListener("load", isAllXhrComplete);
    return open.apply(this, arguments);
  };
})(XMLHttpRequest.prototype.open);

这很可能是复制到的。尽管它是关于
setTimeout
的,但原因仍然是一样的。虽然有一个问题是,您调用的是
isAllXhrComplete()
,而不是传递它,但我真的不会覆盖原始方法来做您想做的事情。您可以通过创建一个管理一组XHR调用的函数来实现这一点。