2016-07-19 3 views
1

In meiner Javascript-Datei für eine Seite möchte ich einige Skripte ausführen, nachdem alle XHR zurückgekehrt sind. Ich weiß, dass es ajaxStop() für XHR-Anfragen durch jquery gibt, aber da ich Mithril verwende und es einen eigenen Wrapper um Ajax hat, kann ich ajaxStop() nicht wirklich verwenden. Ich habe auch einige andere Lösungen versucht, wieWarten auf alle XHR auf einer Seite in JavaScript zu beenden

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); 

Aber es scheint, dass da alle XHR Anrufe separat gebrannt werden, damit die window.activeAjaxCount immer 1 oder 0 wäre, die Ausführung von Skripts auf jedem fertigen XHR Anfrage ausgelöst wird.

Gibt es irgendwelche guten Möglichkeiten, auf alle XHR-Anfragen zu warten?

+0

Es ist wahrscheinlich ein Duplikat [Aufruf von Funktionen mit setTimeout()] (http://stackoverflow.com/questions/3800512/calling- Funktionen-mit-settimeout). Obwohl es sich um 'setTimeout' handelt, ist der Grund immer noch der gleiche. –

+1

Während ein Problem ist, dass Sie 'isAllXhrComplete()' aufrufen, anstatt es zu übergeben, würde ich wirklich nicht die ursprünglichen Methoden überschreiben, um zu tun, was Sie wollen. Sie können dazu eine Funktion erstellen, die eine Gruppe von XHR-Anrufen verwaltet. –

Antwort

2

Ihr Fehler ist hier:

this.addEventListener("load", isAllXhrComplete()); 

die isAllXhrComplete nicht als Rückruf übergeben, weil Sie es sofort anrufen. Stattdessen wird das Ergebnis des Aufrufs isAllXhrComplete() übergeben.

Sie haben zu schreiben:

this.addEventListener("load", isAllXhrComplete); 

Außer, dass Sie sollten wirklich vorsichtig sein, wenn Sie die vorhandenen Funktionen wickeln. Ein korrekter Weg wäre:

(function(send) { 
    XMLHttpRequest.prototype.send = function() { 
     window.activeAjaxCount++; 
     return send.apply(this, arguments); 
    }; 
})(XMLHttpRequest.prototype.send); 

Der wichtige Teil ist, dass Sie das Ergebnis der ursprünglichen Funktion return, und dass Sie verwenden apply alle möglichen Argumente zu übergeben. Andernfalls könnten Sie den Code in Zukunft brechen, wenn die Signatur dieser Funktionen geändert wird.

Ihre Notwendigkeit, das gleiche mit dem open Wrapper zu tun:

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