Es scheint, dass fast jeder asynchrone Anforderungen mit XMLHttpRequest ausführt, aber offensichtlich zeigt die Tatsache, dass es die Möglichkeit gibt, synchrone Anforderungen auszuführen, dass es einen gültigen Grund dafür gibt. Was könnte dieser gültige Grund sein?
javascript
ajax
Darrell Brogdon
quelle
quelle
Antworten:
Ich denke, sie könnten mit fortschreitenden HTML 5-Standards populärer werden. Wenn eine Webanwendung Zugriff auf Web-Worker erhält, könnte ich davon ausgehen, dass Entwickler einen dedizierten Web-Worker verwenden, um synchrone Anforderungen zu stellen, um sicherzustellen, dass eine Anforderung vor der anderen erfolgt, wie Jonathan sagte. In der aktuellen Situation eines Threads ist dies ein weniger als ideales Design, da es blockiert, bis die Anforderung abgeschlossen ist.
quelle
Synchrone XHRs sind nützlich zum Speichern von Benutzerdaten. Wenn Sie das
beforeunload
Ereignis behandeln, können Sie Daten auf den Server hochladen, während der Benutzer die Seite schließt.Wenn dies mit der asynchronen Option durchgeführt würde, könnte die Seite geschlossen werden, bevor die Anforderung abgeschlossen ist. Wenn Sie dies synchron tun, wird sichergestellt, dass die Anforderung in der erwarteten Weise abgeschlossen wird oder fehlschlägt.
quelle
Aktualisieren:
Das Folgende deutete darauf hin, dass es mit dem Aufkommen einer besseren asynchronen Anforderungsbearbeitung wirklich keinen Grund gibt, synchrone Anforderungen zu verwenden, es sei denn, die Absicht, die Benutzer absichtlich daran zu hindern, etwas zu tun, bis eine Anforderung abgeschlossen ist, klingt bösartig: )
Obwohl dies schlecht klingt, kann es Zeiten geben, in denen es wichtig ist, dass eine Anforderung (oder eine Reihe von Anforderungen) auftritt, bevor ein Benutzer eine Seite verlässt oder bevor eine Aktion ausgeführt wird - das Blockieren der Ausführung anderer Codes (z. B. das Verhindern der Zurück-Schaltfläche) könnte dies tun möglicherweise Fehler / Wartung für ein schlecht entworfenes System reduzieren ; Das heißt, ich habe es noch nie in freier Wildbahn gesehen und betont, dass es vermieden werden sollte.
Bibliotheken täuschen wie Versprechen Synchronizität vor, indem sie Prozesse über Rückrufe verketten. Dies entspricht den meisten Entwicklungsanforderungen, bei denen der Wunsch besteht, nicht blockierende Ereignisse zu bestellen, die es den Browsern ermöglichen, die Reaktionsfähigkeit für den Benutzer beizubehalten (gute UX).
Wie in den Mozilla-Dokumenten angegeben, gibt es Fälle, in denen Sie synchrone Anforderungen verwenden müssen. Es wird jedoch auch eine Problemumgehung aufgeführt, bei der Beacon (in IE / Safari nicht verfügbar) für solche Fälle verwendet wird. Während dies experimentell ist, könnte es, falls es jemals die Akzeptanz von Standards erreicht, möglicherweise einen Nagel in den Sarg für synchrone Anfragen stecken.
Sie möchten synchrone Aufrufe in jeder Art von transaktionsähnlicher Verarbeitung ausführen oder überall dort, wo eine Betriebsreihenfolge erforderlich ist.
Angenommen, Sie möchten ein Ereignis anpassen, um sich nach dem Abspielen eines Songs abzumelden. Wenn der Abmeldevorgang zuerst ausgeführt wird, wird das Lied niemals abgespielt. Dies erfordert die Synchronisierung der Anforderungen.
Ein weiterer Grund wäre die Arbeit mit einem WebService, insbesondere wenn Sie auf dem Server rechnen.
Es gibt sehr wenige Fälle, in denen ein synchroner Anruf in einem allgemeinen Beispiel der realen Welt gerechtfertigt sein kann. Möglicherweise, wenn Sie auf Anmelden und dann auf einen Teil der Site klicken, für den ein Benutzer angemeldet sein muss.
Wie andere gesagt haben, wird es Ihren Browser binden, also halten Sie sich von ihm fern, wo Sie können.
Anstelle von synchronen Aufrufen möchten Benutzer jedoch häufig ein Ereignis stoppen, das gerade geladen wird, und dann einen anderen Vorgang ausführen. In gewisser Weise ist dies eine Synchronisation, da das erste Ereignis beendet wird, bevor das zweite beginnt. Verwenden Sie dazu die abort () -Methode für das XML-Verbindungsobjekt.
quelle
Ich würde sagen, wenn Sie erwägen, den Browser des Benutzers zu blockieren, während die Anforderung akzeptabel abgeschlossen ist, verwenden Sie auf jeden Fall eine synchrone Anforderung.
Wenn die Serialisierung von Anforderungen Ihr Ziel ist, kann dies mithilfe von asynchronen Anforderungen erreicht werden, indem der onComplete-Rückruf Ihrer vorherigen Anforderung die nächste Zeile auslöst.
quelle
Es gibt viele reale Fälle, in denen das Blockieren der Benutzeroberfläche genau das gewünschte Verhalten ist.
Nehmen Sie eine App mit mehreren Feldern und einige Felder müssen durch einen xmlhttp-Aufruf an einen Remote-Server überprüft werden, der als Eingabe den Wert dieses Felds und andere Feldwerte bereitstellt.
Im synchronen Modus ist die Logik einfach, die Blockierung durch den Benutzer ist sehr kurz und es gibt kein Problem.
Im asynchronen Modus kann der Benutzer die Werte anderer Felder ändern, während das erste validiert wird. Diese Änderungen lösen andere xmlhttp-Aufrufe mit Werten aus dem Anfangsfeld aus, die noch nicht überprüft wurden. Was passiert, wenn die Erstvalidierung fehlgeschlagen ist? Pures Durcheinander. Wenn der Synchronisierungsmodus veraltet und verboten ist, wird die Anwendungslogik zu einem Albtraum. Grundsätzlich muss die Anwendung neu geschrieben werden, um Sperren zu verwalten (z. B. andere Elemente während des Validierungsprozesses deaktivieren). Die Komplexität des Codes nimmt enorm zu. Andernfalls kann es zu einem Logikfehler und letztendlich zu einer Beschädigung der Daten kommen.
Grundsätzlich stellt sich die Frage: Was ist wichtiger, nicht blockierte Benutzeroberflächenerfahrung oder das Risiko einer Datenkorruption? Die Antwort sollte beim Anwendungsentwickler bleiben, nicht beim W3C.
quelle
Ich kann eine Verwendung für synchrone XHR-Anforderungen sehen, die verwendet werden sollen, wenn eine Ressource an einem variablen Speicherort vor anderen statischen Ressourcen auf der Seite geladen werden muss, die von der ersten Ressource abhängen, die vollständig funktioniert. Tatsächlich implementiere ich eine solche XHR-Anforderung in einem eigenen kleinen Teilprojekt, während sich JavaScript-Ressourcen abhängig von einer Reihe spezifischer Parameter an variablen Speicherorten auf dem Server befinden. Nachfolgende JavaScript-Ressourcen basieren auf diesen variablen Ressourcen, und es muss garantiert werden, dass solche Dateien geladen werden, bevor die anderen abhängigen Dateien geladen werden, wodurch die Anwendung vollständig wird.
Diese Ideengrundlage erweitert die Antwort von vol7ron wirklich. Transaktionsbasierte Prozeduren sind wirklich die einzige Zeit, in der synchrone Anforderungen gestellt werden sollten. In den meisten anderen Fällen sind asynchrone Aufrufe die bessere Alternative, bei der das DOM nach dem Aufruf nach Bedarf aktualisiert wird. In vielen Fällen, z. B. bei benutzerbasierten Systemen, können bestimmte Funktionen für "nicht autorisierte Benutzer" gesperrt sein, bis sie sich per se angemeldet haben. Diese Funktionen werden nach dem asynchronen Aufruf über ein DOM-Aktualisierungsverfahren entsperrt.
Abschließend muss ich sagen, dass ich den Punkten der meisten Personen in dieser Angelegenheit zustimme: Wo immer möglich, sollten synchrone XHR-Anforderungen vermieden werden, da der Browser bei seiner Funktionsweise mit synchronen Anrufen blockiert. Wenn Sie synchrone Anforderungen implementieren, sollten diese so ausgeführt werden, dass der Browser normalerweise ohnehin gesperrt ist, z. B. im Abschnitt HEAD, bevor die Seite tatsächlich geladen wird.
quelle
Ab 2015 werden Desktop-Javascript-Apps immer beliebter. Normalerweise ist in diesen Apps beim Laden lokaler Dateien (und das Laden mit XHR ist eine absolut gültige Option) die Ladegeschwindigkeit so hoch, dass es wenig Sinn macht, den Code mit Async zu komplizieren. Natürlich kann es Fälle geben, in denen Async der richtige Weg ist (Anfordern von Inhalten aus dem Internet, Laden wirklich großer Dateien oder einer großen Anzahl von Dateien in einem einzigen Stapel), aber ansonsten funktioniert die Synchronisierung einwandfrei (und ist viel einfacher zu verwenden). .
quelle
jQuery verwendet unter bestimmten Umständen intern synchrones AJAX. Wenn Sie HTML einfügen, das Skripte enthält, führt der Browser diese nicht aus. Die Skripte müssen manuell ausgeführt werden. Diese Skripte können Klick-Handler anhängen. Angenommen, ein Benutzer klickt auf ein Element, bevor der Handler angehängt wird, und die Seite würde nicht wie beabsichtigt funktionieren. Um Rennbedingungen zu vermeiden, wird daher synchrones AJAX verwendet, um diese Skripte abzurufen. Da synchrones AJAX effektiv alles andere blockiert, kann sichergestellt werden, dass Skripte und Ereignisse in der richtigen Reihenfolge ausgeführt werden.
quelle
Was passiert, wenn Sie im Produktionscode einen synchronen Aufruf tätigen?
Der Himmel fällt herunter.
Nein im Ernst, der Benutzer mag keinen gesperrten Browser.
quelle
Ich benutze es, um einen Benutzernamen zu validieren, während ich überprüfe, ob der Benutzername noch nicht existiert.
Ich weiß, dass es besser wäre, dies asynchron zu tun, aber dann sollte ich einen anderen Code für diese bestimmte Validierungsregel verwenden. Ich erkläre es besser. Mein Validierungssetup verwendet einige Validierungsfunktionen, die je nach Gültigkeit der Daten true oder false zurückgeben.
Da die Funktion zurückkehren muss, kann ich keine asynchronen Techniken verwenden, also mache ich das einfach synchron und hoffe, dass der Server schnell genug antwortet, um nicht zu auffällig zu sein. Wenn ich einen AJAX-Rückruf verwenden würde, müsste ich den Rest der Ausführung anders als die anderen Validierungsmethoden behandeln.
quelle
false
) und es auf true oder false setzt, wenn der Server antwortet. Beim Ändern des Feldes setzen Sie das Flag zurück und rufen den Server erneut an.Manchmal haben Sie eine Aktion, die von anderen abhängt. Beispielsweise kann Aktion B nur gestartet werden, wenn A beendet ist. Der synchrone Ansatz wird normalerweise verwendet, um Rennbedingungen zu vermeiden . Manchmal ist die Verwendung eines synchronen Aufrufs eine einfachere Implementierung als die Erstellung einer komplexen Logik, um jeden Zustand Ihrer asynchronen Aufrufe zu überprüfen, der voneinander abhängt.
Das Problem bei diesem Ansatz besteht darin, dass Sie den Browser des Benutzers "blockieren", bis die Aktion abgeschlossen ist (bis die Anforderung zurückgegeben, beendet, geladen usw. wird). Seien Sie also vorsichtig, wenn Sie es verwenden.
quelle
Ich verwende synchrone Aufrufe bei der Entwicklung von Code. Was auch immer Sie getan haben, während die Anforderung zum und vom Server pendelte, kann die Fehlerursache verschleiern.
Wenn es funktioniert, mache ich es asynchron, aber ich versuche, einen Abbruch-Timer und Fehler-Rückrufe einzuschließen, weil Sie nie wissen ...
quelle
Grund:
Angenommen, Sie haben eine Ajax-Anwendung, die ein halbes Dutzend http ausführen muss, um verschiedene Daten vom Server zu laden, bevor der Benutzer eine Interaktion ausführen kann.
Offensichtlich möchten Sie, dass dies durch Onload ausgelöst wird.
Synchrone Aufrufe funktionieren hierfür sehr gut, ohne dass der Code komplexer wird. Es ist einfach und unkompliziert.
Nachteil:
Der einzige Nachteil ist, dass Ihr Browser abstürzt, bis alle Daten geladen sind oder eine Zeitüberschreitung auftritt. Die betreffende Ajax-Anwendung ist kein großes Problem, da die Anwendung erst dann von Nutzen ist, wenn alle anfänglichen Daten geladen sind.
Alternative?
Viele Browser sperren jedoch alle Fenster / Registerkarten, wenn das Javascript in einem von ihnen ausgelastet ist, was ein dummes Problem beim Browserdesign darstellt. Infolgedessen ist das Blockieren in möglicherweise langsamen Netzwerken nicht höflich, wenn Benutzer keine anderen Registerkarten verwenden während Sie darauf warten, dass die Ajax-Seite geladen wird.
Es sieht jedoch so aus, als ob synchrone Abrufe ohnehin aus den letzten Browsern entfernt oder eingeschränkt wurden. Ich bin mir nicht sicher, ob das daran liegt, dass jemand entschieden hat, dass sie einfach immer schlecht sind, oder ob Browser-Autoren durch den WC-Arbeitsentwurf zu diesem Thema verwirrt waren.
http://www.w3.org/TR/2012/WD-XMLHttpRequest-20120117/#the-open-method lässt es so aussehen (siehe Abschnitt 4.7.3), dass Sie im Blockierungsmodus kein Timeout festlegen dürfen . Scheint mir kontraintuitiv zu sein: Wenn jemand E / A blockiert, ist es höflich, ein angemessenes Zeitlimit festzulegen. Warum also das Blockieren von E / A zulassen, jedoch nicht mit einem benutzerdefinierten Zeitlimit?
Meiner Meinung nach spielt das Blockieren von E / A in einigen Situationen eine wichtige Rolle, muss aber korrekt implementiert werden. Es ist zwar nicht akzeptabel, dass eine Browser-Registerkarte oder ein Browser-Fenster alle anderen Registerkarten oder Fenster blockiert, dies ist jedoch ein Fehler im Browser-Design. Schande, wo Schande gebührt. In einigen Fällen ist es jedoch durchaus akzeptabel, dass ein einzelner Tab oder ein Fenster in einigen Situationen einige Sekunden lang nicht reagiert (z. B. durch Blockieren von IO / HTTP GET), z. B. beim Laden von Seiten, möglicherweise bei vielen Daten muss sein, bevor irgendetwas getan werden kann. Manchmal ist richtig implementierter Blockierungscode der sauberste Weg, dies zu tun.
Natürlich kann in diesem Fall eine äquivalente Funktion mit asynchronen http-Gets erhalten werden, aber welche Art von doofer Routine ist erforderlich?
Ich denke, ich würde etwas in diese Richtung versuchen:
Gehen Sie beim Laden des Dokuments wie folgt vor: 1: Richten Sie 6 globale "Done" -Flag-Variablen ein, die auf 0 initialisiert sind. 2: Führen Sie alle 6 Hintergrundabrufe aus (vorausgesetzt, die Reihenfolge spielt keine Rolle).
Dann würden die Abschlussrückrufe für jedes der 6 http-Get's ihre jeweiligen "Done" -Flaggen setzen. Außerdem würde jeder Rückruf alle anderen erledigten Flags überprüfen, um festzustellen, ob alle 6 HTTP-Abschlüsse abgeschlossen wurden. Der letzte zu vervollständigende Rückruf, der sah, dass alle anderen abgeschlossen waren, rief dann die REAL-Init-Funktion auf, die dann alles einrichtete, nachdem alle Daten abgerufen worden waren.
Wenn die Reihenfolge des Abrufs von Bedeutung ist oder wenn der Webserver nicht in der Lage ist, mehrere Anforderungen gleichzeitig zu akzeptieren, benötigen Sie Folgendes:
In onload () wird der erste http get gestartet. In seinem Rückruf würde der zweite gestartet. In seinem Rückruf der dritte - und so weiter und so fort, wobei jeder Rückruf das nächste HTTP-GET startet. Wenn der letzte zurückkehrte, rief er die echte init () - Routine auf.
quelle
SYNC vs ASYNC: Was ist der Unterschied?
Im Grunde läuft es darauf hinaus:
Wenn dies synchron
doSomething
ist, wird Folgendes gedruckt:Wenn dies dagegen asynchron ist ,
doSomething
wird Folgendes gedruckt:Da die Funktion
doSomething
ihre Arbeit asynchron ausführt, kehrt sie zurück, bevor ihre Arbeit erledigt ist. Das Ergebnis erhalten wir also erst nach dem DruckenGoodbye cruel world!
Wenn wir vom Ergebnis eines asynchronen Aufrufs abhängig sind, müssen wir den abhängigen Code in den Rückruf einfügen:
Daher ist nur die Tatsache, dass zwei oder drei Dinge in der Reihenfolge geschehen müssen, kein Grund, sie synchron auszuführen (obwohl der Synchronisierungscode für die meisten Menschen einfacher zu handhaben ist).
WARUM SYNCHRONE XMLHTTPREQUEST VERWENDEN?
In einigen Situationen benötigen Sie das Ergebnis, bevor die aufgerufene Funktion abgeschlossen ist. Stellen Sie sich dieses Szenario vor:
Angenommen, wir haben keine Kontrolle über den aufrufenden Code (die
console.info
Leitung) und müssen die Funktion ändernlives
, um den Server zu fragen ... Wir können auf keinen Fall eine asynchrone Anforderung an den Server von innen ausführenlives
und haben unsere Antwort noch vorlives
Abschluss. Wir würden also nicht wissen, ob wir zurückkehren sollentrue
oder nichtfalse
. Die einzige Möglichkeit, das Ergebnis vor Abschluss der Funktion zu erhalten, besteht in einer synchronen Anforderung.Wie
Sami Samhuri
in seiner Antwort erwähnt, ist dasonbeforeunload
Ereignis ein sehr reales Szenario, in dem Sie möglicherweise eine Antwort auf Ihre Serveranforderung benötigen, bevor Ihre Funktion beendet wird , da es die letzte Funktion Ihrer App ist, die jemals ausgeführt wird, bevor das Fenster geschlossen wird.ICH BRAUCHE KEINE SYNCH CALLS, ABER ICH BENUTZE SIE JEDERZEIT, WIE SIE EINFACHER SIND
Bitte nicht. Synchrone Anrufe sperren Ihren Browser und sorgen dafür, dass die App nicht mehr reagiert. Aber Sie haben Recht. Async-Code ist schwieriger. Es gibt jedoch eine Möglichkeit, den Umgang damit viel einfacher zu gestalten. Nicht so einfach wie Synchronisierungscode, aber es kommt näher: Versprechen s.
Hier ein Beispiel: Zwei asynchrone Aufrufe sollten beide erfolgreich abgeschlossen werden, bevor ein drittes Codesegment ausgeführt werden kann:
So würden Sie implementieren
bookHotel
:Siehe auch: Besseres JavaScript mit Versprechen schreiben .
quelle
XMLHttpRequest
wird traditionell für asynchrone Anforderungen verwendet. Manchmal (zum Debuggen oder für eine bestimmte Geschäftslogik) möchten Sie alle / mehrere asynchrone Aufrufe auf einer Seite für die Synchronisierung ändern.Sie möchten dies tun, ohne alles in Ihrem JS-Code zu ändern. Das Async / Sync-Flag bietet Ihnen diese Möglichkeit. Bei korrekter Gestaltung müssen Sie nur eine Zeile in Ihrem Code ändern / den Wert von 1
var
während der Ausführungszeit ändern .quelle
Firefox (und wahrscheinlich alle Nicht-IE-Browser) unterstützt kein asynchrones XHR timeOut.
HTML5- WebWorker unterstützen Zeitüberschreitungen. Daher möchten Sie möglicherweise die Synchronisierungs-XHR-Anforderung mit Zeitüberschreitung an WebWorker umschließen, um asynchrones XHR mit Zeitüberschreitungsverhalten zu implementieren.
quelle
Ich hatte gerade eine Situation, in der asynchrone Anforderungen für eine Liste von URLs, die nacheinander mit forEach (und einer for-Schleife) aufgerufen wurden, dazu führten, dass die verbleibenden Anforderungen abgebrochen wurden. Ich habe auf synchron umgestellt und sie funktionieren wie vorgesehen.
quelle
Die Verwendung synchroner HTTP-Anforderungen ist im Geschäft mit mobiler Werbung eine gängige Praxis.
Unternehmen (auch bekannt als "Publisher"), die Anwendungen erstellen, schalten häufig Anzeigen, um Einnahmen zu erzielen. Dazu installieren sie Werbe-SDKs in ihrer App. Viele existieren (MoPub, Ogury, TapJob, AppNext, Google Ads AdMob).
Diese SDKs liefern Anzeigen in einer Webansicht.
Wenn Sie eine Anzeige für einen Nutzer schalten , muss dies eine reibungslose Erfahrung sein, insbesondere beim Abspielen eines Videos. Es sollte zu keinem Zeitpunkt gepuffert oder geladen werden.
Um dies zu lösen,
precaching
wird verwendet. Wo die Medien (Bild / Videos / usw.) synchron im Hintergrund der Webansicht geladen werden.Warum nicht asynchron?
onload
Ereignis weiß, wann die Anzeige "bereit" ist, um dem Nutzer geliefert zu werdenMit der Ablehnung synchroner XMLHttpRequests wird das Anzeigengeschäft höchstwahrscheinlich gezwungen sein, den Standard in Zukunft zu ändern, sofern kein anderer Weg festgelegt werden kann.
quelle
Synchrones XHR kann für die Entwicklung interner Tools und / oder Frameworks (ohne Produktion) sehr nützlich sein. Stellen Sie sich zum Beispiel vor, Sie möchten beim ersten Zugriff eine Codebibliothek synchron laden:
Denken Sie daran, dass dies nur für lokale Tests gedacht ist, bevor Sie sich in ein Schwindelgefühl versetzen und blind das Böse der Eval erbrechen. Für Produktions-Builds wäre _draw bereits festgelegt.
Ihr Code könnte also folgendermaßen aussehen:
Dies ist nur ein Beispiel für etwas, das ohne die Synchronisierung von XHR nicht möglich wäre. Sie könnten diese Bibliothek im Voraus laden, ja, oder ein Versprechen / einen Rückruf machen, aber Sie könnten die Bibliothek nicht synchron laden, ohne XHR zu synchronisieren. Überlegen Sie, wie viel diese Art von Dingen Ihren Code bereinigen könnte ...
Die Grenzen dessen, was Sie damit für Werkzeuge und Frameworks (lokal ausgeführt) tun können, sind nur durch Ihre Vorstellungskraft begrenzt. Es scheint jedoch, dass die Vorstellungskraft in der JavaScript-Welt etwas eingeschränkt ist.
quelle
Hier ist ein guter Grund. Ich wollte eine http-Anfrage machen und dann je nach Ergebnis click () für einen Eingabetyp = file aufrufen. Dies ist mit asynchronem xhr oder fetch nicht möglich. Der Rückruf verliert den Kontext "Benutzeraktion", sodass der Aufruf click () ignoriert wird. Synchrones xhr hat meinen Speck gerettet.
quelle