Was passiert eigentlich im Hintergrund, da JavaScript in einem einzelnen Thread ausgeführt wird, nachdem eine AJAX-Anforderung gestellt wurde? Ich würde gerne einen tieferen Einblick bekommen, kann jemand etwas Licht ins Dunkel bringen?
Was passiert eigentlich im Hintergrund, da JavaScript in einem einzelnen Thread ausgeführt wird, nachdem eine AJAX-Anforderung gestellt wurde? Ich würde gerne einen tieferen Einblick bekommen, kann jemand etwas Licht ins Dunkel bringen?
Antworten:
Unter dem Deckblatt hat Javascript eine Ereigniswarteschlange. Jedes Mal, wenn ein Javascript-Ausführungsthread beendet wird, wird überprüft, ob sich ein anderes zu verarbeitendes Ereignis in der Warteschlange befindet. Wenn dies der Fall ist, wird es aus der Warteschlange entfernt und dieses Ereignis ausgelöst (z. B. durch einen Mausklick).
Das native Code-Netzwerk, das sich unter dem Ajax-Aufruf befindet, weiß, wann die Ajax-Antwort abgeschlossen ist, und ein Ereignis wird zur Javascript-Ereigniswarteschlange hinzugefügt. Wie der native Code weiß, wann der Ajax-Aufruf ausgeführt wird, hängt von der Implementierung ab. Es kann mit Threads implementiert werden oder es kann auch selbst ereignisgesteuert sein (es spielt keine Rolle). Der Punkt der Implementierung ist, dass, wenn die Ajax-Antwort fertig ist, ein nativer Code weiß, dass sie fertig ist, und ein Ereignis in die JS-Warteschlange stellt.
Wenn zu diesem Zeitpunkt kein Javascript ausgeführt wird, wird das Ereignis sofort ausgelöst, wodurch der Ajax-Antworthandler ausgeführt wird. Wenn gerade etwas ausgeführt wird, wird das Ereignis verarbeitet, wenn der aktuelle Javascript-Ausführungsthread beendet ist. Die Javascript-Engine muss keine Abfrage durchführen. Wenn die Ausführung eines Teils von Javascript abgeschlossen ist, überprüft die JS-Engine nur die Ereigniswarteschlange, um festzustellen, ob noch etwas ausgeführt werden muss. In diesem Fall wird das nächste Ereignis aus der Warteschlange entfernt und ausgeführt (Aufruf einer oder mehrerer Rückruffunktionen, die für dieses Ereignis registriert sind). Befindet sich nichts in der Ereigniswarteschlange, hat der JS-Interpreter freie Zeit (Speicherbereinigung oder Leerlauf), bis ein externer Agent etwas anderes in die Ereigniswarteschlange stellt und es erneut aktiviert.
Da alle externen Ereignisse die Ereigniswarteschlange durchlaufen und kein Ereignis jemals ausgelöst wird, während Javascript tatsächlich etwas anderes ausführt, bleibt es Single-Threaded.
Hier sind einige Artikel zu den Details:
.focus()
ein Objekt auf und dies löst einige andere Ereignisse aus, z. B. ein "Unschärfe" -Ereignis für das Objekt mit Fokus. Dieses Unschärfeereignis geschieht synchron und durchläuft die Ereigniswarteschlange nicht, sodass es sofort vor anderen Dingen in der Ereigniswarteschlange auftritt. In der Praxis habe ich dies nie als praktisches Problem empfunden.
Sie können finden hier eine sehr vollständige Dokumentation über die Ereignisse in Javascript Handhabung.
Es wurde von einem Mann geschrieben, der an der Javascript-Implementierung im Opera-Browser arbeitet.
Schauen Sie sich die Titel genauer an: "Ereignisablauf", "Ereigniswarteschlange" und "Nichtbenutzerereignisse": Sie werden Folgendes erfahren:
Hinweis: Ursprünglicher Link war: Link , ist aber jetzt tot.
Ich möchte etwas näher auf die in den Antworten erwähnte Ajax-Implementierung eingehen.
Obwohl (regular) ist Javascript Ausführung nicht multi-threaded - wie auch in den oben genannten Antworten festgestellt - aber die eigentliche Umgang mit der AJAX responses
(wie auch die Anforderungsbehandlung) ist nicht Javascript, und es - in der Regel - ist multi-threaded. (Siehe die Implementierung von XMLHttpRequest in Chromquellen, auf die wir oben eingehen werden.)
und ich erkläre, nehmen wir den folgenden Code:
var xhr = new XMLHttpRequest();
var t = Date.now;
xhr.open( "GET", "https://swx.cdn.skype.com/shared/v/1.2.15/SkypeBootstrap.min.js?v="+t(), true );
xhr.onload = function( e ) {
console.log(t() + ': step 3');
alert(this.response.substr(0,20));
};
console.log(t() + ': step 1');
xhr.send();
console.log(t() + ': step 2');
after an AJAX request is made
(- nach Schritt 1), während Ihr js-Code weiter ausgeführt wird (Schritt 2 und danach), beginnt der Browser mit der eigentlichen Arbeit von: 1. Formatieren einer TCP-Anfrage 2. Öffnen eines Sockets 3. Senden von Headern 4. Handshaking 5. Senden body 6. wartende Antwort 7. Lesen von Headern 8. Lesen von body usw. Die gesamte Implementierung wird normalerweise in einem anderen Thread parallel zur Ausführung Ihres js-Codes ausgeführt. Zum Beispiel verwendet die erwähnte Chrom-Implementierung Threadable Loader go digg-into 😉 (Sie können sich auch einen Eindruck verschaffen, indem Sie auf die Registerkarte "Netzwerk" einer Seitenladung schauen, und Sie sehen einige gleichzeitige Anforderungen).
Abschließend würde ich sagen, dass - zumindest - die meisten Ihrer E / A-Vorgänge gleichzeitig / asynchron ausgeführt werden können (und Sie können dies beispielsweise mit einem Warten nutzen ). Alle Interaktionen mit diesen Operationen (die Ausgabe, die js-Rückrufausführung) sind jedoch alle synchron.