Ist es möglich, dass mit jQuery, ich eine Ajax-Anfrage abbrechen/verhindern von dem ich noch keine Antwort erhalten habe?
Antworten
Zu viele Anzeigen?Es ist immer die beste Praxis, so etwas zu tun.
var $request;
if ($request != null){
$request.abort();
$request = null;
}
$request = $.ajax({
type : "POST", //TODO: Must be changed to POST
url : "yourfile.php",
data : "data"
}).done(function(msg) {
alert(msg);
});
Aber es ist viel besser, wenn Sie eine if-Anweisung, um zu überprüfen, ob die Ajax-Anfrage ist null oder nicht.
Wir mussten dieses Problem einfach umgehen und haben drei verschiedene Ansätze getestet.
- storniert die Anfrage wie von @meouw vorgeschlagen
- alle Anfragen ausführen, aber nur das Ergebnis der letzten Anfrage verarbeiten
-
verhindert neue Anfragen, solange eine andere Anfrage noch anhängig ist
var Ajax1 = { call: function() { if (typeof this.xhr !== 'undefined') this.xhr.abort(); this.xhr = $.ajax({ url: 'your/long/running/request/path', type: 'GET', success: function(data) { //process response } }); } }; var Ajax2 = { counter: 0, call: function() { var self = this, seq = ++this.counter; $.ajax({ url: 'your/long/running/request/path', type: 'GET', success: function(data) { if (seq === self.counter) { //process response } } }); } }; var Ajax3 = { active: false, call: function() { if (this.active === false) { this.active = true; var self = this; $.ajax({ url: 'your/long/running/request/path', type: 'GET', success: function(data) { //process response }, complete: function() { self.active = false; } }); } } }; $(function() { $('#button').click(function(e) { Ajax3.call(); }); })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input id="button" type="button" value="click" />
In unserem Fall haben wir uns für den Ansatz Nr. 3 entschieden, da er eine geringere Belastung des Servers zur Folge hat. Ich bin mir aber nicht 100%ig sicher, ob jQuery den Aufruf der .complete()-Methode garantiert, dies könnte zu einer Deadlock-Situation führen. In unseren Tests konnten wir eine solche Situation nicht reproduzieren.
Sie können jeden fortlaufenden Ajax-Aufruf abbrechen, indem Sie diese
<input id="searchbox" name="searchbox" type="text" />
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
var request = null;
$('#searchbox').keyup(function () {
var id = $(this).val();
request = $.ajax({
type: "POST", //TODO: Must be changed to POST
url: "index.php",
data: {'id':id},
success: function () {
},
beforeSend: function () {
if (request !== null) {
request.abort();
}
}
});
});
</script>
Rufen Sie einfach xhr an. Abbrechen() ob es sich um ein Jquery Ajax Objekt oder ein natives XMLHTTPRequest Objekt handelt.
Beispiel:
//jQuery ajax
$(document).ready(function(){
var xhr = $.get('/server');
setTimeout(function(){xhr.abort();}, 2000);
});
//native XMLHTTPRequest
var xhr = new XMLHttpRequest();
xhr.open('GET','/server',true);
xhr.send();
setTimeout(function(){xhr.abort();}, 2000);
Wie viele in diesem Thread festgestellt haben, wird der Server die Anfrage dennoch bearbeiten, nur weil sie auf der Client-Seite abgebrochen wurde. Dies führt zu einer unnötigen Belastung des Servers, da er Arbeiten ausführt, die wir auf dem Frontend nicht mehr hören.
Das Problem, das ich zu lösen versuchte (und auf das auch andere stoßen könnten), bestand darin, dass ich bei der Eingabe von Informationen in ein Eingabefeld eine Anfrage für eine Art Google Instant absetzen wollte.
Um unnötige Anfragen zu vermeiden und die Schnelligkeit des Frontends zu erhalten, habe ich Folgendes getan:
var xhrQueue = [];
var xhrCount = 0;
$('#search_q').keyup(function(){
xhrQueue.push(xhrCount);
setTimeout(function(){
xhrCount = ++xhrCount;
if (xhrCount === xhrQueue.length) {
// Fire Your XHR //
}
}, 150);
});
Dadurch wird im Wesentlichen alle 150 ms eine Anfrage gesendet (eine Variable, die Sie für Ihre eigenen Bedürfnisse anpassen können). Wenn Sie Probleme haben zu verstehen, was genau hier passiert, protokollieren Sie xhrCount
y xhrQueue
auf der Konsole kurz vor dem if-Block.