[javascript] Bricht Ajax-Anfragen mit jQuery ab


Answers

Sie können die Anforderung nicht abrufen, aber Sie können einen Zeitüberschreitungswert festlegen, nach dem die Antwort ignoriert wird. Siehe diese page für jquery AJAX Optionen. Ich glaube, dass Ihr Fehler Callback aufgerufen wird, wenn die Zeitüberschreitung überschritten wird. Für jede AJAX-Anfrage gibt es bereits eine Standard-Zeitüberschreitung.

Sie können auch die abort() -Methode für das Anforderungsobjekt verwenden. Dies führt zwar dazu, dass der Client nicht mehr auf das Ereignis wartet, der Server kann ihn jedoch möglicherweise nicht mehr verarbeiten.

Question

Wie kann ich mit jQuery eine Ajax-Anfrage abbrechen / abbrechen , von der ich noch keine Antwort erhalten habe?




Ich habe eine demo , die zeigt, wie man eine AJAX-Anfrage abbricht - wenn Daten nicht innerhalb einer vordefinierten Wartezeit vom Server zurückgegeben werden.

HTML:

<div id="info"></div>

JS CODE:

var isDataReceived= false, waitTime= 1000; 
$(function() {
    // Ajax request sent.
     var xhr= $.ajax({
      url: 'http://api.joind.in/v2.1/talks/10889',
      data: {
         format: 'json'
      },     
      dataType: 'jsonp',
      success: function(data) {      
        isDataReceived= true;
        $('#info').text(data.talks[0].talk_title);        
      },
      type: 'GET'
   });
   // Cancel ajax request if data is not loaded within 1sec.
   setTimeout(function(){
     if(!isDataReceived)
     xhr.abort();     
   },waitTime);   
});






Wir mussten dieses Problem nur umgehen und testeten drei verschiedene Ansätze.

  1. storniert die Anfrage wie von @meouw vorgeschlagen
  2. Führe alle Anfragen aus, verarbeitet aber nur das Ergebnis der letzten Übermittlung
  3. verhindert neue Anfragen, solange noch eine aussteht

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 der Server weniger belastet wird. Aber ich bin nicht 100% sicher, wenn jQuery den Aufruf der .complete () - Methode garantiert, könnte dies zu einer Deadlock-Situation führen. In unseren Tests konnten wir eine solche Situation nicht reproduzieren.




Ich hatte das Problem des Pollings und sobald die Seite geschlossen wurde, ging die Umfrage weiter. In meinem Fall würde ein Benutzer ein Update verpassen, da ein Mysql-Wert für die nächsten 50 Sekunden nach Schließen der Seite gesetzt wurde, obwohl ich die Ajax-Anfrage, I, beendete Um es herum zu finden, benutze $ _SESSION, um eine Variable zu setzen, wird nicht in der Abfrage selbst aktualisiert, bis sie beendet ist und eine neue begonnen hat. Also habe ich einen Wert in meiner Datenbank als 0 = offpage gesetzt, während ich bin polling Ich frage diese Zeile ab und gebe false zurück; Wenn es 0 ist, wenn Sie in der Abfrage abfragen, erhalten Sie offensichtlich aktuelle Werte ...

Ich hoffe, das hat geholfen




Wie viele Leute im Thread bemerkt haben, wird der Server die Anfrage immer noch verarbeiten, nur weil die Anfrage auf der Client-Seite abgebrochen wird. Dies erzeugt eine unnötige Belastung für den Server, da es Arbeiten ausführt, auf die wir im Front-End nicht mehr hören.

Das Problem, das ich zu lösen versuchte (das andere auch dazu führen können), besteht darin, dass ich, wenn der Benutzer Informationen in ein Eingabefeld eingab, eine Anfrage nach einem Google Instant-Gefühl auslösen wollte.

Um unnötige Anfragen zu vermeiden und das Snappiness des Frontends beizubehalten, 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);

});

Dies sendet im Wesentlichen alle 150ms eine Anfrage (eine Variable, die Sie für Ihre eigenen Bedürfnisse anpassen können). Wenn Sie nicht genau xhrQueue , was genau hier passiert, loggen Sie xhrCount und xhrQueue vor dem if-Block in die Konsole ein.




es gibt keinen zuverlässigen Weg, es zu tun, und ich würde es nicht einmal versuchen, sobald die Anfrage unterwegs ist; Die einzige Möglichkeit, vernünftig zu reagieren, besteht darin , die Antwort zu ignorieren .

In den meisten Fällen kann es passieren, dass ein Benutzer zu oft auf eine Schaltfläche klickt, die viele aufeinanderfolgende XHRs auslöst. Hier haben Sie viele Möglichkeiten: entweder die Schaltfläche sperren, bis XHR zurückgegeben wird, oder gar kein neues XHR auslösen, während ein anderer Hinting ausführt der Benutzer, um sich zurückzulehnen - oder verwerfen alle ausstehenden XHR-Antwort, aber die jüngsten.




Speichern Sie die Anrufe, die Sie in einem Array tätigen, und rufen Sie dann je xhr.abort () auf.

RIESIGE HÖHE: Sie können eine Anfrage abbrechen, aber das ist nur die Client-Seite. Die Serverseite könnte die Anfrage noch bearbeiten. Wenn Sie etwas wie PHP oder ASP mit Sitzungsdaten verwenden, sind die Sitzungsdaten gesperrt, bis der Ajax beendet ist. Damit der Benutzer die Website weiter durchsuchen kann, müssen Sie session_write_close () aufrufen. Dies speichert die Sitzung und entsperrt sie, so dass andere Seiten, die darauf warten, fortzufahren, fortfahren werden. Andernfalls können mehrere Seiten darauf warten, dass das Schloss entfernt wird.






Links