Heim  >  Artikel  >  Web-Frontend  >  Beherrschen Sie den JavaScript-Ausführungsmechanismus vollständig

Beherrschen Sie den JavaScript-Ausführungsmechanismus vollständig

WBOY
WBOYnach vorne
2022-01-20 17:58:50962Durchsuche

Dieser Artikel bringt Ihnen verwandte Themen zum JavaScript-Ausführungsmechanismus, einschließlich Wissen über JavaScript-Single-Threading und JavaScript-Synchronisierung und -Asynchronität. Ich hoffe, dass er für alle hilfreich ist.

Beherrschen Sie den JavaScript-Ausführungsmechanismus vollständig

1. Warum JavaScript Single-Threaded ist

Wenn Sie verstehen möchten, warum JavaScript Single-Threaded ist, müssen wir damit beginnen, für welche Arbeit JavaScript verwendet wird.

Als Skriptsprache für Browser besteht der Zweck von JavaScript darin, dass der Browser mit Benutzern interagiert und DOM-Elemente bedient, wodurch die Benutzerinteraktion und -erfahrung verbessert wird. JavaScript muss das DOM-Element des Browsers bedienen, daher kann JavaScript nicht zu einer Multithread-Sprache werden, in der zwei Threads ein DOM-Element gleichzeitig bearbeiten müssen Aktualisieren Sie das DOM-Element, und der andere Thread muss das DOM-Element bearbeiten und aktualisieren. Welches soll der Browser verwenden?

Sie können nur das Gleiche gleichzeitig tun. Aufgrund der Funktionsweise von DOM-Elementen ist Single-Threading der Kern und das Merkmal der JavaScript-Sprache.

HTML5 schlägt den Web Worker-Standard vor, der es JavaScript-Skripten ermöglicht, mehrere Threads zu erstellen, aber die untergeordneten Threads werden vollständig vom Hauptthread gesteuert und dürfen das DOM nicht bedienen. Selbst solche Änderungen ändern nichts an der Single-Threaded-Natur von js.

2. Synchronisation und Asynchronität in JavaScript

Der Single-Thread-Mechanismus von JavaScript führt dazu, dass nur eine Sache gleichzeitig erledigt werden kann. Genauso wie eine Gruppe von Leuten, die Geld an einem Geldautomaten abheben, auch wenn hinter ihnen noch mehr Leute stehen, die es eilig haben, können sie sich nur einer nach dem anderen anstellen und darauf warten, dass die erste Person Geld abhebt, bevor sie an der Reihe ist die nächste Person.

Aber das führt dazu, dass die nächste Aufgabe sehr lange warten muss, wenn die vorherige Aufgabe zu lange dauert. Wenn wir beispielsweise eine Ajax-Anfrage mit einer sehr großen Datenmenge laden müssen, müssen wir warten das entsprechende Ergebnis der Anfrage, bevor Sie fortfahren und nachfolgende Aufgaben ausführen.

Wie sollen wir also mit dieser Situation umgehen? Da wir den Single-Thread-Mechanismus von JavaScript nicht ändern können, können wir einige Langzeitaufgaben vorübergehend anhalten und warten, bis die Hauptaufgabe abgeschlossen ist, bevor wir diese bereitgestellten Aufgaben ausführen? Der Autor von JavaScript hat auch so gedacht. JavaScript hat synchrone Aufgaben und asynchrone Aufgaben.

Synchronisierte Aufgaben bedeuten, dass Aufgaben im Hauptthread in die Warteschlange gestellt werden und die nächste Aufgabe auf den Abschluss der vorherigen Aufgabe warten muss, bevor sie ausgeführt werden kann. Eine asynchrone Aufgabe bedeutet, dass die Aufgabe nicht in den Hauptthread eintritt, sondern in die Aufgabenwarteschlange eintritt. Die Aufgabe, die in die Aufgabenwarteschlange eintritt, wird nur dann eingegeben, wenn die „Aufgabenwarteschlange“ den Hauptthread benachrichtigt, dass eine asynchrone Aufgabe ausgeführt werden kann. Ausführung des Hauptthreads.

3. Ereignisschleifenmechanismus

Alle Synchronisierungsaufgaben von JavaScript werden im Hauptthread ausgeführt und bilden einen Ausführungsstapel.

Die Aufgabenwarteschlange basiert auf dem First-In-First-Out-Prinzip. Ereignisse in der erweiterten Warteschlange werden zuerst ausgeführt, Ereignisse in der letzten Warteschlange werden später ausgeführt.

Ereignisschleife

  • Synchronisationsaufgaben im Ausführungsstapel ausführen.

  • Wenn eine asynchrone Aufgabe auftritt, wird nicht auf das Rückgabeergebnis gewartet. Die asynchrone Aufgabe wird vorübergehend angehalten und andere synchrone Aufgaben werden weiterhin ausgeführt.

  • Wenn die asynchrone Aufgabe Ergebnisse liefert, wird die JavaScript-Aufgabe zur Aufgabenwarteschlange hinzugefügt. Zur Aufgabenwarteschlange hinzugefügte Aufgaben werden nicht sofort per Rückruf ausgeführt, sondern warten, bis der Hauptthread (Ausführungsstapel) inaktiv ist, bevor sie zum Ausführungsstapel zur Rückrufausführung hinzugefügt werden

  • Warten auf die Aufgaben im Ausführungsstapel ausgeführt werden.

  • Fügen Sie die Aufgabe in der Aufgabenwarteschlange zum Ausführungsstapel hinzu und führen Sie sie aus.

Immer wieder entsteht so eine Endlosschleife. (Das Bild unten stammt aus dem Internet)

Beherrschen Sie den JavaScript-Ausführungsmechanismus vollständig

Nachdem wir Event Loop gelernt haben, werfen wir einen Blick auf die folgende Frage:

setTimeout(function(){
     console.log('setTimeout start')
 });
 new Promise(function(resolve){
     console.log('promise start');
     resolve()
 }).then(function(){
     console.log('promise then')
 });
 console.log('script end');

Versuchen Sie, eine Analyse gemäß dem JavaScript-Ausführungsmechanismus durchzuführen, den wir gerade oben gelernt haben

1. Zuerst ausführen Synchronisation Die Aufgabe wird bis setTimeout ausgeführt, aber setTimeout ist eine vorübergehende Unterbrechung der asynchronen Aufgabe und wartet darauf, dass das Timeout zur Aufgabenwarteschlange hinzugefügt wird.

2. Fahren Sie fort und führen Sie ein neues Versprechen aus. Neues Versprechen enthält Synchronisierungsaufgaben und gibt „Versprechen Start“ aus.

3. Fügen Sie .then zur Aufgabenwarteschlange hinzu, nachdem Sie „resolve“ ausgeführt haben.

4. Beim Ausführen von console.log('script end'); geben Sie "script end" aus.

5. Zu diesem Zeitpunkt wurde die Hauptaufgabe ausgeführt. Fügen Sie die asynchrone Aufgabe zur Hauptaufgabe hinzu und führen Sie sie direkt aus. Geben Sie „setTimeout start“ aus, fügen Sie dann „.then“ zur Hauptaufgabe hinzu und geben Sie „promise then“ aus.

Das Ergebnis sollte also lauten: Promise Start –> SetTimeout Start –> Ende - > Versprechen dann -> setTimeout start

Makroaufgaben und Mikroaufgaben

Warum stimmen die oben genannten Ergebnisse dann nicht mit unseren Erwartungen überein? Warum wird setTimeout start nach dem Versprechen gedruckt?

Tatsächlich liegt es daran, dass die asynchrone Ausführung auch sequentiell ist. Tatsächlich ist es ungenau, asynchrone und synchrone Methoden zu verwenden, um die Ausführungsreihenfolge von Aufgabenwarteschlangen aufzuteilen. Es sollte in Mikrotasks und Makrotasks unterteilt werden.

  • Makroaufgabe: Skriptcode, setTimeout, setInterval

  • Mikroaufgabe: Promise, process.nextTick

SetTimeout ist also eine Makroaufgabe in asynchronen Aufgaben. Promise ist eine Mikroaufgabe in asynchronen Aufgaben. Unabhängig davon, ob es sich um eine Mikroaufgabe oder eine Makroaufgabe handelt, wird sie in die entsprechende Ereigniswarteschlange eingegeben. Als nächstes betrachten wir ein Flussdiagramm.

Beherrschen Sie den JavaScript-Ausführungsmechanismus vollständig

Lassen Sie es uns ein wenig verstehen:

  • 1. Makroaufgaben ausführen (Skriptcode)

  • 2. Wenn beim Ausführen einer Makroaufgabe eine Mikroaufgabe auftritt, wird die Mikroaufgabe hinzugefügt die Ereigniswarteschlange

  • 3. Nachdem die Ausführung der aktuellen Makroaufgabe abgeschlossen ist, wird die Ereigniswarteschlange der Mikroaufgabe angezeigt und alle darin enthaltenen Mikroaufgaben werden nacheinander ausgeführt

  • 4. Nach der Ausführung Alle Mikroaufgaben, fahren Sie fort. Der erste Schritt besteht darin, diese Schleife auszuführen

Dies ist auch der Funktionsmechanismus von JavaScript. In Kombination damit werden wir das obige Beispiel erneut analysieren.

  • 1. Führen Sie zuerst die Makroaufgabe (Skriptcode) aus und fügen Sie sie der Ereigniswarteschlange der Makroaufgabe hinzu, wenn setTimeout auftritt.

  • 2. Führen Sie weiterhin ein neues Versprechen aus und geben Sie „Versprechen Start“ aus.

  • 3. Nach der Ausführung zur Auflösung ist .then die Mikrotask und wird zur Ereigniswarteschlange der Mikrotask hinzugefügt.

  • 4. Beim Ausführen von console.log('script end'); geben Sie „script end“ aus.

  • 5. Zu diesem Zeitpunkt wurden alle Makroaufgaben dieser Runde ausgeführt. Überprüfen Sie zu diesem Zeitpunkt, ob in der Eevent-Warteschlange der Mikroaufgaben ausführbare Mikroaufgaben vorhanden sind Im dritten Schritt führen Sie dann „Versprechen dann“ aus. 6. Zu diesem Zeitpunkt ist die erste Runde der Ereignisschleife vollständig beendet. Die nächste Runde der Ereignisschleife führt zunächst eine Makroaufgabe aus und stellt fest, dass die setTimeout wird zur Ereigniswarteschlange der Makroaufgabe hinzugefügt. Führen Sie „setTimeout start“ aus und geben Sie es aus.

  • Denken Sie immer daran, dass JavaScript Single-Threaded ist, es immer war, ist und auch in Zukunft sein wird. Alles Gerede über Multithreading ist Schwachsinn.

  • Even Event Queue ist nicht nur eine Möglichkeit zur asynchronen Implementierung, sondern auch ein Ausführungsmechanismus von js.

Es kann in Zukunft mit JavaScript implementiert werden. Alles wird mit JavaScript implementiert.

Verwandte Empfehlungen:

Javascript-Lern-Tutorial

Das obige ist der detaillierte Inhalt vonBeherrschen Sie den JavaScript-Ausführungsmechanismus vollständig. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen