Heim  >  Artikel  >  Web-Frontend  >  Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

青灯夜游
青灯夜游nach vorne
2022-01-05 10:29:572456Durchsuche

In diesem Artikel erfahren Sie, warum der Browser und Node.js EventLoop so entwerfen. Ich hoffe, dass es für alle hilfreich ist!

Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

Event Loop ist ein Grundkonzept von JavaScript. Es ist ein Muss in Interviews und wird im täglichen Leben oft erwähnt. Aber haben Sie jemals darüber nachgedacht, warum es Event Loop gibt und warum es so konzipiert ist?

Heute werden wir den Gründen auf den Grund gehen.

Die Ereignisschleife des Browsers

JavaScript wird zur Implementierung der Webseiten-Interaktionslogik verwendet, die Dom-Operationen umfasst. Der Einfachheit halber sind Synchronisierung und gegenseitiger Ausschluss erforderlich. Threaded, aber wenn es Single-Threaded ist, wird es blockiert, wenn es auf Timing-Logik und Netzwerkanforderungen stößt. Was zu tun?

Sie können eine Ebene der Planungslogik hinzufügen. Kapseln Sie einfach den JS-Code in Aufgaben und stellen Sie sie in eine Aufgabenwarteschlange. Der Hauptthread ruft dann weiterhin Aufgaben ab und führt sie aus.

Jedes Mal, wenn eine Aufgabe abgerufen und ausgeführt wird, wird ein neuer Aufrufstapel erstellt.

Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

Dabei werden Timer und Netzwerkanforderungen tatsächlich in anderen Threads ausgeführt. Nach der Ausführung wird eine Aufgabe in die Aufgabenwarteschlange gestellt, um den Hauptthread anzuweisen, die Ausführung fortzusetzen.

Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

Da diese asynchronen Aufgaben in anderen Threads ausgeführt und dann über die Aufgabenwarteschlange an den Hauptthread benachrichtigt werden, handelt es sich um einen Ereignismechanismus, daher wird diese Schleife als Ereignisschleife bezeichnet.

Zu diesen asynchronen Aufgaben, die in anderen Threads ausgeführt werden, gehören Timer (setTimeout, setInterval), UI-Rendering und Netzwerkanforderungen (XHR oder fetch).

Es gibt jedoch ein ernstes Problem mit der aktuellen Ereignisschleife. Es gibt kein Prioritätskonzept und sie wird nur der Reihe nach ausgeführt. Wenn es Aufgaben mit hoher Priorität gibt, werden diese nicht rechtzeitig ausgeführt. Daher muss ein Warteschlangensprungmechanismus entworfen werden.

Dann erstellen Sie einfach eine Aufgabenwarteschlange mit hoher Priorität. Nachdem jede normale Aufgabe ausgeführt wurde, werden alle Aufgaben mit hoher Priorität ausgeführt, und dann werden die normalen Aufgaben ausgeführt.

Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

Mit dem Warteschlangensprungmechanismus können hochwertige Aufgaben zeitnah ausgeführt werden.

Dies ist die aktuelle Browser-Ereignisschleife.

Die gewöhnlichen Aufgaben heißen MacroTask (Makroaufgaben) und die hochwertigen Aufgaben heißen MicroTasks (Mikroaufgaben).

Makroaufgaben umfassen: setTimeout, setInterval, requestAnimationFrame, Ajax, fetch, Skript-Tag-Code.

Zu den Mikrotasks gehören: Promise.then, MutationObserver, Object.observe.

Wie versteht man die Aufteilung von Makro- und Mikroaufgaben?

Timer und Netzwerkanforderungen sind gängige asynchrone Logik, die den Hauptthread benachrichtigt, nachdem andere Threads ihre Ausführung beendet haben, es handelt sich also allesamt um Makroaufgaben.

Die drei Arten von Qualitätsaufgaben sind ebenfalls leicht zu verstehen. Änderungen in einem Objekt müssen sofort erfolgen, sonst kann es zu Änderungen kommen , dann ist der Aufruf am asynchronen Ende auch sehr gut.

Dies ist das Design der Ereignisschleife im Browser: Der Schleifenmechanismus und die Aufgabenwarteschlange sollen die asynchrone Ausführung unterstützen und das Problem lösen, dass die Logikausführung den Hauptthread blockiert. Der Warteschlangensprungmechanismus der MicroTask-Warteschlange soll das Problem lösen Problem der frühzeitigen Ausführung hochwertiger Aufgaben.

Aber später war die Ausführungsumgebung von JS nicht nur ein Browser, sondern auch Node.js, das diese Probleme ebenfalls lösen musste, aber die von ihm entworfene Ereignisschleife war detaillierter. Die Ereignisschleife von

Node.js ist eine neue JS-Laufumgebung. Sie unterstützt auch asynchrone Logik, einschließlich Timer, E/A und Netzwerkanforderungen.

Allerdings ist die Ereignisschleife des Browsers für Hochleistungsserver konzipiert, das Design ist jedoch noch etwas grob.

Wo ist es rau?

Die Ereignisschleife des Browsers ist nur in zwei Prioritätsstufen unterteilt, eine für Makroaufgaben und eine für Mikroaufgaben. Es gibt jedoch keine weitere Priorisierung zwischen Makroaufgaben und keine weitere Priorisierung zwischen Mikroaufgaben.

Und die Aufgabenmakroaufgaben von Node.j haben beispielsweise eine höhere Priorität als die von IO, denn je früher, desto genauer ist sie und desto höher ist die Priorität der Verarbeitungslogik Ressourcen schließen Es ist sehr niedrig, denn wenn es nicht geschlossen wird, belegt es höchstens mehr Speicher und andere Ressourcen und die Auswirkungen sind nicht groß.

Daher wurde die Makroaufgabenwarteschlange in fünf Prioritätsstufen unterteilt: Timer, Ausstehend, Abfrage, Prüfen und Schließen.

Erklären Sie diese fünf Makroaufgaben:

Timer-Rückruf: Wenn es um die Zeit geht, gilt: Je früher die Ausführung, desto genauer ist sie. Dies hat also höchste Priorität und ist leicht zu verstehen.

Ausstehender Rückruf: Rückruf bei der Behandlung von Netzwerk-, E/A- und anderen Ausnahmen. Einige *niux-Systeme warten auf die Meldung von Fehlern und müssen daher behandelt werden.

Poll Callback: Die Verarbeitung von E/A-Daten und Netzwerkverbindungen wird hauptsächlich vom Server erledigt.

Rückruf prüfen: Führen Sie den Rückruf von setImmediate aus. Die Besonderheit besteht darin, dass dieser direkt nach der Ausführung von IO zurückgerufen werden kann.

Rückruf schließen: Ein Rückruf, der Ressourcen schließt, hat keine Auswirkungen und hat die niedrigste Priorität.

So läuft also die Event-Schleife von Node.js ab:

Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

Es gibt noch einen weiteren Unterschied, auf den Sie besonders achten sollten:

Die Event-Schleife von Node.js ist nicht die Art von Browser, die Führt jeweils eine Makroaufgabe aus und führt dann alle Mikroaufgaben aus, führt jedoch eine bestimmte Anzahl von Timer-Makroaufgaben aus, führt dann alle Mikroaufgaben aus, führt dann eine bestimmte Anzahl ausstehender Makroaufgaben aus und führt dann alle Mikroaufgaben sowie die verbleibenden Abfragen und Prüfungen aus , das Gleiche gilt für die Makroaufgabe „Schließen“. (Korrektur: Dies war vor Knoten 11 der Fall. Nach Knoten 11 wurde geändert, dass bei jeder Makroaufgabe alle Mikroaufgaben ausgeführt werden)

Warum ist das so?

Tatsächlich ist es in Bezug auf die Priorität leicht zu verstehen:

Angenommen, die Priorität der Makroaufgabe im Browser ist 1, sodass sie der Reihe nach ausgeführt wird, dh eine Makroaufgabe, alle Mikroaufgaben usw dann eine Makroaufgabe. Alle Mikroaufgaben.

Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

Und die Makroaufgaben von Node.js haben auch Prioritäten, daher führt die Ereignisschleife von Node.js alle Makroaufgaben mit der aktuellen Priorität aus, bevor die Mikroaufgaben ausgeführt werden, und führt die Mikroaufgaben dann erneut aus die Makroaufgabe mit der nächsten Priorität.

Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

Das heißt, eine bestimmte Anzahl von Timer-Makroaufgaben, dann alle Mikroaufgaben, dann eine bestimmte Anzahl von ausstehenden Rückruf-Makroaufgaben und dann alle Mikroaufgaben.

Warum soll es sich um eine bestimmte Menge handeln?

Denn wenn in einer bestimmten Phase zu viele Makroaufgaben vorhanden sind, wird die nächste Phase nie ausgeführt, sodass es eine Obergrenze gibt und die verbleibende Ereignisschleife weiterhin ausgeführt wird.

Zusätzlich zur Priorität von Makroaufgaben werden Mikroaufgaben auch in Prioritäten unterteilt. Es gibt eine zusätzliche Mikroaufgabe mit hoher Priorität, Process.nextTick, die vor allen gewöhnlichen Mikroaufgaben ausgeführt wird.

Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

Der gesamte Prozess der Node.js-Ereignisschleife sieht also wie folgt aus:

  • Timers-Stufe: Führen Sie eine bestimmte Anzahl von Timern aus, d sie bis zum nächsten Mal ausführen
  • Mikrotasks: Führen Sie alle nextTick-Mikrotasks aus und führen Sie dann andere gewöhnliche Mikrotasks aus
  • Ausstehende Phase: Führen Sie eine bestimmte Anzahl von E/A- und Netzwerkausnahmerückrufen aus. Wenn es zu viele sind, überlassen Sie sie der nächsten Ausführung
  • Mikrotasks: Führen Sie alle NextTick-Mikrotasks aus und führen Sie dann andere gewöhnliche Mikrotasks aus. Führen Sie eine bestimmte Anzahl von Dateidaten-Rückrufen und Netzwerkverbindungs-Rückrufen aus. Wenn zu viele vorhanden sind, überlassen Sie diese der nächsten Ausführung.
  • Wenn es keinen E/A-Rückruf gibt und keine Timer und Prüfphasenrückrufe zum Verarbeiten vorhanden sind, blockieren Sie einfach hier und warten Sie auf E/A-Ereignisse. Führen Sie eine bestimmte Anzahl von setImmediate-Rückrufen aus. Wenn zu viele vorhanden sind, werden diese beim nächsten Mal ausgeführt.
  • Mikrotasks: Führen Sie alle nextTick-Mikrotasks aus und führen Sie dann andere gewöhnliche Mikrotasks aus.
  • Schließphase: Führen Sie eine bestimmte Anzahl von Rückrufen für Abschlussereignisse aus. Wenn es zu viele sind, belassen Sie sie für die nächste Ausführung.
  • Mikrotasks: Alle nextTick-Mikrotasks ausführen und dann andere gewöhnliche Mikrotasks ausführenIm Vergleich zur Ereignisschleife im Browser ist es natürlich viel komplizierter, aber nach unserer vorherigen Analyse können wir auch Folgendes verstehen:
  • Knoten. js hat Makroaufgaben (Timer, Ausstehend, Abfrage, Prüfung und Schließen) von hoch nach niedrig priorisiert und auch Mikroaufgaben unterteilt, d. h. nextTick-Mikroaufgaben und andere Mikroaufgaben. Der Ausführungsprozess besteht darin, zuerst eine bestimmte Anzahl von Makrotasks mit der aktuellen Priorität auszuführen (den Rest für den nächsten Zyklus zu belassen), dann die Mikrotasks von Process.nextTick auszuführen, dann normale Mikrotasks auszuführen und dann eine bestimmte Anzahl mit der nächsten Priorität auszuführen . Anzahl der Makroaufgaben. . Dieser Zyklus geht weiter. Es gibt auch eine Leerlauf-/Vorbereitungsphase für die interne Logik von Node.j, sodass Sie sich darüber keine Sorgen machen müssen.
  • Die Art und Weise der Ausführung jeweils einer Makroaufgabe in der Browser-Ereignisschleife wurde geändert, wodurch Makroaufgaben mit hoher Priorität früher ausgeführt werden können, aber auch eine Obergrenze festgelegt wird, um zu verhindern, dass die nächste Stufe nicht ausgeführt wird.

    Es gibt noch einen weiteren Punkt, auf den Sie besonders achten sollten, nämlich die Umfragephase: Wenn Sie die Umfragephase ausführen und feststellen, dass die Umfragewarteschlange leer ist und in der Timer-Warteschlange und der Prüfwarteschlange keine auszuführenden Aufgaben vorhanden sind, dann Sie werden blockiert und warten hier auf das IO-Ereignis, anstatt im Leerlauf zu sein. Dieses Design liegt auch daran, dass der Server hauptsächlich E/A verarbeitet und das Blockieren hier früher auf E/A reagieren kann.

    Die vollständige Ereignisschleife von Node.js sieht folgendermaßen aus:

    Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

    Vergleichen Sie die Ereignisschleife des Browsers:

    Entdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!

    Die allgemeinen Designideen der Ereignisschleife der beiden JS-Laufumgebungen sind ähnlich, außer Die Node-Ereignisschleife von .js ermöglicht eine feinere Aufteilung von Makroaufgaben und Mikroaufgaben, was leicht zu verstehen ist. Schließlich unterscheidet sich die Umgebung von Node.js von der von Browsern. Noch wichtiger sind die Leistungsanforderungen des Servers wird höher sein.

    Zusammenfassung

    JavaScript wurde zunächst zum Schreiben von Webseiten-Interaktionslogik verwendet. Um das Synchronisierungsproblem zu vermeiden, bei dem mehrere Threads das DOM gleichzeitig ändern, wurde es als einzelner Thread konzipiert Für das Problem eines einzelnen Threads wurde eine Ebene der Planungslogik hinzugefügt, d. Um die Aufgabenplanung mit hoher Priorität zu unterstützen, wurden dann Mikroaufgabenwarteschlangen eingeführt. Dies ist der Ereignisschleifenmechanismus des Browsers: Jedes Mal wird eine Makroaufgabe ausgeführt, und dann werden alle Mikroaufgaben ausgeführt.

    Node.js ist auch eine JS-Laufumgebung. Wenn Sie asynchron unterstützen möchten, müssen Sie auch Event Loop verwenden. Allerdings ist die Serverumgebung komplexer und stellt höhere Leistungsanforderungen, sodass Node.js besser funktioniert -Körnige Makro- und Mikroaufgaben:

    Node.js ist in 5 Arten von Makroaufgaben unterteilt, nämlich Timer, Ausstehend, Abfrage, Prüfung und Schließen. Es werden zwei Arten von Mikrotasks unterschieden, nämlich Process.nextTick-Mikrotasks und andere Mikrotasks.

    Der Ereignisschleifenprozess von Node.js besteht darin, eine bestimmte Anzahl von Makroaufgaben in der aktuellen Phase auszuführen (der Rest wird in der nächsten Schleife ausgeführt) und dann alle Mikroaufgaben auszuführen. Es gibt Timer, Ausstehende, Leerlauf /Vorbereiten, Befragen, Prüfen, Schließen 6 Stufen. (Korrektur: Dies war vor Knoten 11 der Fall. Nach Knoten 11 wurde geändert, dass bei jeder Makroaufgabe alle Mikroaufgaben ausgeführt werden)

    Die Phase „Leerlauf/Vorbereitung“ wird intern von Node.js verwendet, also machen Sie sich darüber keine Sorgen Es.

    Besondere Aufmerksamkeit sollte der Umfragephase gewidmet werden und die Timer- und Prüfwarteschlangen sind ebenfalls leer. Hier wird auf IO gewartet, bis Rückrufe in den Timer- und Prüfwarteschlangen vorliegen, bevor die Umfrage fortgesetzt wird Schleife.

    Event Loop ist eine von JS entwickelte Planungslogik zur Unterstützung von Asynchronität und Aufgabenpriorität. Sie verfügt über unterschiedliche Designs für verschiedene Umgebungen wie Browser und Node.js (hauptsächlich aufgrund der unterschiedlichen Granularität der Aufgabenpriorität). komplexere Umgebungen und höhere Leistungsanforderungen, sodass das Design der Ereignisschleife komplexer ist.

    Weitere Informationen zu Knoten finden Sie unter:

    nodejs-Tutorial! !

Das obige ist der detaillierte Inhalt vonEntdecken Sie, warum Browser und Node.js EventLoop auf diese Weise entwickelt haben!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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