In diesem Artikel wird hauptsächlich der JS-Browser-Ereignisschleifenmechanismus vorgestellt, der einen gewissen Referenzwert hat. Jetzt können Freunde in Not darauf zurückgreifen.
Lassen Sie uns zunächst einige konzeptionelle Inhalte verstehen.
Ein Prozess ist eine vom System zugewiesene unabhängige Ressource und die Grundeinheit der CPU-Ressourcenzuweisung. Ein Prozess besteht aus einem oder mehreren Threads.
Thread ist der Ausführungsfluss eines Prozesses und die Grundeinheit der CPU-Planung und -Verteilung. Mehrere Threads im selben Prozess teilen sich die Ressourcen des Prozesses.
Der Browser ist ein Multiprozess-Browser, und jede Registerkartenbezeichnung im Browser stellt einen unabhängigen Prozess dar (nicht unbedingt, da mehrere). leere Tab-Beschriftungen werden zu einem Prozess zusammengeführt), der Browser-Kernel (Browser-Rendering-Prozess) ist einer der Multiprozesse des Browsers.
Im Browserkernel arbeiten mehrere Threads.
Wenn Sie eine HTTP-Anfrage stellen, wird ein Anfragethread geöffnet.
Nachdem die Anfrage abgeschlossen ist und das Ergebnis erhalten wurde, fügen Sie die angeforderte Rückruffunktion zur Aufgabenwarteschlange hinzu und warten Sie auf die Verarbeitung durch die JS-Engine.
Der Browser-Timing-Zähler wird von der JS-Engine nicht gezählt und das Blockieren führt zu einem ungenauen Timing.
Aktivieren Sie den Timer-Trigger-Thread, um die Zeitmessung durchzuführen und auszulösen. Nachdem die Zeitmessung abgeschlossen ist, wird sie zur Aufgabenwarteschlange hinzugefügt und wartet auf die Verarbeitung durch die JS-Engine.
Wenn ein Ereignis die Auslösebedingungen erfüllt und ausgelöst wird, fügt der Thread die entsprechende Ereignisrückruffunktion am Ende der Aufgabenwarteschlange hinzu und wartet auf die Verarbeitung durch die JS-Engine.
Single-Threaded-Arbeit, verantwortlich für das Parsen und Ausführen von JavaScript-Skripten.
und der GUI-Rendering-Thread schließen sich gegenseitig aus. Wenn die Ausführung von JS zu lange dauert, wird die Seite blockiert.
ist für das Rendern der Seite, das Parsen von HTML, CSS zur Bildung eines DOM-Baums usw. verantwortlich. Dieser Thread wird aufgerufen, wenn die Seite neu gezeichnet wird oder ein Reflow durch einen Vorgang verursacht wird.
und der JS-Engine-Thread schließen sich gegenseitig aus. Wenn der JS-Engine-Thread funktioniert, wird der GUI-Rendering-Thread angehalten und das GUI-Update wird in die JS-Aufgabenwarteschlange gestellt. wartet. Der JS-Engine-Thread setzt die Ausführung fort, wenn er inaktiv ist.
GUI-Rendering-Thread:
JS-Engine-Thread:
Ereignisauslösender Thread:
Timer-Trigger-Thread:
http-Anfrage-Thread:
Die JavaScript-Engine ist Single-Threaded, was bedeutet, dass jeweils nur eine Aufgabe ausgeführt werden kann und andere Aufgaben in die Warteschlange gestellt werden müssen, um ausgeführt zu werden. Nur die aktuelle Aufgabe wird ausgeführt. Nach Abschluss wird die nächste Aufgabe ausgeführt.
Die Web-Worker-API wird in HTML5 hauptsächlich zur Lösung des Problems der Seitenblockierung vorgeschlagen, ändert jedoch nichts an der Single-Threaded-Natur von JavaScript. Erfahren Sie mehr über Web-Worker.
Der JavaScript-Ereignisschleifenmechanismus ist in Browser- und Node-Ereignisschleifenmechanismen unterteilt. Die Implementierungstechnologien der beiden sind unterschiedlich Die Ereignisschleife wird von der libuv-Bibliothek implementiert. Das Hauptaugenmerk liegt hier auf dem Browser-Teil.
Javascript verfügt über einen Hauptthread und einen Call-Stack (Ausführungsstack). Alle Aufgaben werden auf dem Call-Stack abgelegt, um auf die Ausführung des Haupt-Threads zu warten.
JS-Aufrufstapel
JS-Aufrufstapel ist eine Last-In-First-Out-Datenstruktur. Wenn eine Funktion aufgerufen wird, wird sie oben auf dem Stapel hinzugefügt. Nach Abschluss der Ausführung wird die Funktion vom oberen Rand des Stapels entfernt, bis der Stapel gelöscht wird.
Synchrone Aufgaben, asynchrone Aufgaben
Die Aufgaben im JavaScript-Einzelthread sind in synchrone Aufgaben und asynchrone Aufgaben unterteilt. Synchrone Aufgaben werden der Reihe nach im Aufrufstapel in die Warteschlange gestellt und warten auf die Ausführung durch den Hauptthread, während asynchrone Aufgaben die registrierte Rückruffunktion zur Aufgabenwarteschlange (Nachrichtenwarteschlange) hinzufügen, nachdem das asynchrone Ergebnis verfügbar ist, und auf die Ausführung durch den Hauptthread warten im Leerlauf, also im Stapel. Wenn es gelöscht ist, wird es in den Stapel eingelesen und wartet auf die Ausführung durch den Hauptthread. Die Aufgabenwarteschlange ist eine First-In-First-Out-Datenstruktur.
Ereignisschleife
Die Synchronisierungsaufgaben im Aufrufstapel wurden ausgeführt und der Stapel wurde gelöscht, was bedeutet, dass der Hauptthread zu diesem Zeitpunkt inaktiv ist. Es wird in die Aufgabenwarteschlange gestellt. Eine Aufgabe wird der Reihe nach gelesen und zur Ausführung auf dem Stapel abgelegt. Jedes Mal, wenn der Stapel geleert wird, wird gelesen, ob sich Aufgaben in der Aufgabenwarteschlange befinden. Wenn Aufgaben vorhanden sind, werden sie gelesen und ausgeführt. Der Lese- und Ausführungsvorgang bildet eine Ereignisschleife.
Timer
Der Timer startet einen Timer Der Timer löst den Thread aus, um das Timing auszulösen. Nach dem Warten auf die angegebene Zeit stellt der Timer das Ereignis in die Aufgabenwarteschlange und wartet darauf, dass es vom Hauptthread gelesen und ausgeführt wird.
Die vom Timer angegebene Verzögerung in Millisekunden ist tatsächlich nicht genau, da der Timer das Ereignis erst dann in die Aufgabenwarteschlange einfügt, wenn die angegebene Zeit erreicht ist, und warten muss, bis die synchronisierte Aufgabe und das Ereignis in der vorhandenen Aufgabenwarteschlange vorhanden sind Wenn alle Ausführungen abgeschlossen sind, werden die Timer-Ereignisse im Hauptthread gelesen und ausgeführt. Es kann vorkommen, dass Aufgaben in der Mitte lange dauern, sodass die Ausführung zum angegebenen Zeitpunkt nicht garantiert werden kann.
Makroaufgabe (Makroaufgabe), Mikroaufgabe (Mikroaufgabe)
Neben verallgemeinerten synchronen Aufgaben und asynchronen Aufgaben auch Aufgaben in einer JavaScript-Einzelaufgabe Der Thread kann detailliert in Makroaufgaben und Mikroaufgaben unterteilt werden.
Makroaufgabe umfasst: Skript (Gesamtcode), setTimeout, setInterval, setImmediate, I/O, UI-Rendering.
Mikroaufgabe umfasst: Process.nextTick, Promises, Object.observe, MutationObserver.
console.log(1); setTimeout(function() { console.log(2); }) var promise = new Promise(function(resolve, reject) { console.log(3); resolve(); }) promise.then(function() { console.log(4); }) console.log(5);
Im Beispiel werden setTimeout und Promise als Aufgabenquellen bezeichnet, und von verschiedenen Aufgabenquellen registrierte Rückruffunktionen werden in verschiedene Aufgabenwarteschlangen gestellt.
Nachdem wir die Konzepte von Makroaufgaben und Mikroaufgaben kennengelernt haben, wie ist die Ausführungsreihenfolge von JS? Sollten Makroaufgaben oder Mikroaufgaben an erster Stelle stehen?
In der ersten Ereignisschleife führt die JavaScript-Engine den gesamten Skriptcode als Makrotask aus. Nach Abschluss der Ausführung erkennt sie, ob sich in dieser Schleife eine Mikrotask befindet, und startet sie Nachdem alle Mikrotasks in der Aufgabenwarteschlange gelesen und ausgeführt wurden, werden die Aufgaben in der Aufgabenwarteschlange der Makrotask gelesen und ausgeführt, und dann werden alle Mikrotasks ausgeführt und so weiter. Die Ausführungssequenz von JS besteht aus Makroaufgaben und Mikroaufgaben in jeder Ereignisschleife.
Im obigen Beispiel gelangt der gesamte Code in der ersten Ereignisschleife als Makroaufgabe zur Ausführung in den Hauptthread.
Wenn setTimeout auftritt, wartet es, bis die angegebene Zeit abgelaufen ist, und stellt die Rückruffunktion in die Aufgabenwarteschlange der Makroaufgabe.
Wenn Sie auf ein Versprechen stoßen, fügen Sie die Funktion then in die Aufgabenwarteschlange der Mikroaufgabe ein.
Nachdem die gesamte Ereignisschleife abgeschlossen ist, erkennt es, ob sich eine Aufgabe in der Aufgabenwarteschlange der Mikrotask befindet, und führt sie aus, falls vorhanden.
Das Ergebnis der ersten Schleife wird wie folgt gedruckt: 1,3,5,4.
Gehen Sie dann zur Aufgabenwarteschlange der Makroaufgabe, nehmen Sie eine Makroaufgabe heraus und legen Sie sie auf den Stapel, damit der Hauptthread sie ausführen kann. Anschließend wird die Makroaufgabe in dieser Schleife ausgeführt ist die von setTimeout registrierte Rückruffunktion. Nach der Ausführung dieser Rückruffunktion wird festgestellt, dass sich in dieser Schleife keine Mikrotasks befinden, und wir sind bereit für die nächste Ereignisschleife.
Wenn festgestellt wird, dass in der Makroaufgabenwarteschlange keine auszuführenden Aufgaben vorhanden sind, wird die Ereignisschleife beendet.
Das Endergebnis ist 1,3,5,4,2.
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er wird für das Studium aller hilfreich sein. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.
Verwandte Empfehlungen:
Das obige ist der detaillierte Inhalt vonJS-Browser-Ereignisschleifenmechanismus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!