Ajax-Rennbedingungen

8

Gibt es ein Muster oder eine Standardmethode für den Umgang mit Ajax-Rennbedingungen? Nehmen Sie das folgende Beispiel. Sie haben zwei Tabellen. Durch Klicken auf eine Zeile in Tabelle 1 werden die Daten aus der Datenbank entfernt und anschließend Tabelle 2 aktualisiert (in der nun alle Zeilen von Tabelle 1 abzüglich der angeklickten Zeile angezeigt werden).

Wenn jemand schnell hintereinander auf eine Reihe von Zeilen klickt, kann dies zu einem Szenario führen, in dem Tabelle 2 nicht für alle Klicks aktualisiert wird, die auf Timing- / Verzögerungsprobleme zurückzuführen sind.

Was könnte ein guter Weg sein, um dies zu erreichen? Ich habe darüber nachgedacht, eine mögliche Warteschlange zu verwenden, aber diese Art von Niederlage macht den Zweck zunichte, dies asynchron zu tun. Ich hätte jedoch immer noch den Vorteil, dass die Benutzeroberfläche nicht gesperrt wird.

Ominus
quelle
AJAX und Datenbanken? Wie kommen die beiden dabei zusammen?
Oded
Ja, ich war irgendwie vage. Es ist eine Web-App mit Daten, die über Ajax gesendet / abgerufen werden, genauer gesagt jQuery.get / post.
Ominus

Antworten:

8

Nur ein Gedanke, vielleicht könnten Sie eine Liste für Ihre Ajax-Rückrufmethoden erstellen. Sie würden Ihren tatsächlichen Ajax-Rückruf in eine Methode einschließen, die diesen Rückruf einem Slot in einer Liste hinzufügt.

Diese Liste wartet in einer bestimmten Reihenfolge auf Rückrufe und wird nur ausgeführt, wenn das oberste Element (der Rückruf, den Sie zuerst aufrufen möchten) gefüllt ist.

Greg
quelle
1
Das programmgesteuerte Verschachteln der Rückrufe ist eine solide Lösung.
Sam
7

Dies ist keine Rennbedingung.

Eine Race-Bedingung würde auftreten, wenn das Verhalten zwischen zwei asynchronen Threads undefiniert wird. Sie können dieses Problem lösen, indem Sie den Rückruf vom ersten Anruf an verschachteln

Sam
quelle
6
Aufgrund möglicher Netzwerkprobleme werden nicht alle AJAX-Anrufe mit derselben Geschwindigkeit ausgeführt. Wir sehen es sogar in der Entwicklung in unserem lokalen Netzwerk, wo ein späterer AJAX-Aufruf vor einem früheren beendet wird und die Benutzeroberfläche falsch endet. Rückrufe in Nesting / Queuing lösen das Problem, dies ist jedoch eine Race-Bedingung.
Izkata
1
@Izkata Dies ist falsch, Javascript hat keine Race-Bedingungen, da es auf einem einzelnen Thread ausgeführt wird. Die Situation, die Sie beschreiben, ähnelt dem gleichzeitigen Ausführen von zwei Funktionen, eine zum Öffnen einer Datei und eine zum Lesen des Inhalts der geöffneten Datei. Die Funktion zum Öffnen von Dateien muss vor der Lesefunktion ausgeführt werden. Wenn Sie jedoch beide gleichzeitig ausführen, wird manchmal die zweite Funktion zuerst ausgeführt. Dies ist keine Rennbedingung, es ist nicht in Ordnung, die Dinge richtig zu bestellen. Die richtige Antwort für Javascript im Jahr 2017 besteht darin Promise.then(), asynchrone Rückrufe in der richtigen Reihenfolge auszuführen.
Daniel T.
1
@Izkata Es ist keine Rennbedingung, es ist ein Bestellproblem. Die Anforderung selbst wird nativ vom Browser verarbeitet, der Rückruf wird jedoch im JS-Thread ausgeführt. Race-Bedingungen werden verursacht, wenn zwei Threads, die gleichzeitig ausgeführt werden, dieselbe Ressource gemeinsam nutzen und gleichzeitig in die Ressource lesen / schreiben, was zu einer nicht deterministischen Ausgabe führt. Wenn Sie zwei AJAX-Anforderungen gleichzeitig haben, ist die Ausgabe deterministisch. Es ist entweder das Ergebnis von Rückruf A oder Rückruf B. Was Sie nicht wissen, ist die Reihenfolge , in der die Rückrufe aufgerufen werden. Dies ist nicht anders als die Bereitstellung von zwei Schaltflächen für den Benutzer und
Daniel T.
1
Sie wissen nicht, auf welche Schaltfläche der Benutzer zuerst klickt. Das Ergebnis ist entweder der Rückruf für Taste A oder der Rückruf für Taste B, jedoch niemals eine unvorhersehbare, nicht deterministische Ausgabe. Wenn Sie die Reihenfolge steuern müssen , in der Rückrufe aufgerufen werden, müssen Sie Versprechen verwenden. Das unvorhersehbare Timing des Rückrufaufrufs ist jedoch nicht dasselbe wie die Rennbedingungen.
Daniel T.
1
@Izkata Ein 'unerwartetes Ergebnis' in einer Race-Bedingung bedeutet, dass eine Funktion nicht deterministisch ist, was in JS nicht passiert, weil Sie genau das gesagt haben: "Wenn ein gleichzeitiges Verhalten ein unerwartetes Ergebnis verursachen kann". Das Schlüsselwort hier ist gleichzeitig; AJAX-Anforderungen werden gleichzeitig ausgeführt, Rückrufe jedoch nicht. Daher ist das Ergebnis von Rückruffunktionen in JS immer deterministisch, da sie sequentiell und niemals gleichzeitig ausgeführt werden. Dieser Beitrag ist eine gute Lektüre: blog.raananweber.com/2015/06/17/…
Daniel T.
6

Im Allgemeinen sind Rückrufe ein universelles Werkzeug für den Umgang mit asynchronen Aufgaben, und Rückrufe sind in der Tat der Mechanismus zur Verarbeitung von AJAX-Anforderungen in JavaScript. Im Kontext des Rückrufs können Sie sogar auf die Zeile verweisen, auf die geklickt wird (wenn sie geschlossen wird). Die folgenden Artikel sind nützlich: jQuery zurückgestellt und Verwenden von Zurückgestellt in jQuery

Eine andere Sache, die Sie beachten sollten, wenn der Benutzer auf mehrere Schaltflächen klicken darf, ist, dass mehrere Anforderungen gestartet werden. Unterschiedliche Browser können jedoch unterschiedliche Anzahlen von AJAX-Anforderungen gleichzeitig verarbeiten: Concurrent-Ajax-xmlhttprequest-Anforderungen . Um dies zu überwinden, sollten Sie eine grundlegende Anforderungswarteschlange implementieren.

rusev
quelle
+1 für den einzigen, der über zurückgestellte Dinge spricht.
Florian Margaine