Detaillierte Erläuterung der Ereignisschleifen-Ereigniswarteschlange von js im Browser

Detaillierte Erläuterung der Ereignisschleifen-Ereigniswarteschlange von js im Browser

Vorwort

Der folgende Inhalt ist die Ereigniswarteschlangenausführung von js im Browser, die sich von der in nodejs unterscheidet. Bitte beachten Sie.

Es wird gesagt, dass js ein Single-Thread ist, aber es ist nicht wirklich ein Single-Thread. Bei der Ausführung im Browser wird jedoch nur ein Thread zur Ausführung zugewiesen.

Daher erfolgt die JS-Ausführung einfädig und es kann jeweils nur eine Aufgabe ausgeführt werden, d. h., es wird jeweils eine Aufgabe erledigt und die nächste wird erledigt, nachdem die andere abgeschlossen ist.

Einen Stapel und zwei Warteschlangen verstehen

Ein Aufrufstapel.

Eine Makrowarteschlange, Makrotask, auch Tasks genannt.

Eine Mikrowarteschlange, Mikrotask, auch Jobs genannt.

Ausführungsprozess

js führt den globalen Skriptsynchronisierungscode aus. Wenn während dieses Vorgangs asynchrone Aufgaben auftreten, werden diese zuerst der entsprechenden Warteschlange hinzugefügt.

Wenn dies erledigt ist, ist der Aufrufstapel leer.

Anschließend wird die erste Aufgabe in der Warteschlange (zuerst Mikrowarteschlange, dann Makrowarteschlange) zur Erledigung nacheinander in den Aufrufstapel verschoben, bis alle Aufgaben in der Warteschlange abgeschlossen sind.

Zusammenfassend lässt sich sagen, dass Sie zuerst die Synchronisierungsaufgaben, dann die Mikro-Warteschlangenaufgaben und anschließend die Makro-Warteschlangenaufgaben ausführen müssen.

So verteilen Sie asynchrone Aufgaben

Zu diesen asynchronen Aufgaben gehören unter anderem:

Der Makro-Warteschlange sind zugeordnet:

setTimeout
Intervall festlegen
AnfrageAnimationFrame
E/A
UI-Rendering

Den Mikrowarteschlangen sind folgende Aufgaben zugeordnet:

Versprechen
Objekt.beobachten
MutationObserver

Allgemeine Makro-Warteschlangen: setTimeout, allgemeine Mikro-Warteschlangen: Promise.

Einfaches Beispiel

    console.log("Synchronisierte Aufgabe 1");

    setzeTimeout(() => {
      console.log("Makroaufgabe");
    });

    neues Versprechen((lösen, ablehnen) => {
      console.log("Synchronisierte Aufgabe 2");
      lösen("Mikroaufgabe");
    }).dann((Daten) => {
      konsole.log(Daten);
    });

    console.log("Synchronisierte Aufgabe 3");

Das Ergebnis ist (Aufgaben nach Nummer hinzufügen und mit Pfeiltaste ausführen):

Es ist zu beachten, dass die erste Ebene von Promise synchron ist, bevor der Rückruf ausgeführt wird. Dies ist die synchrone Aufgabe 2 oben.

Ein schwierigeres Beispiel

    console.log("Synchronisierte Aufgabe 1");

    console.log("Synchronisierte Aufgabe 2");

    neues Versprechen((lösen, ablehnen) => {
      console.log("Synchronisierte Aufgabe 3");
      setzeTimeout(() => {
        console.log("Makroaufgabe 1");
        Versprechen.lösen()
          .then(() => {
            console.log("Mikrotask 5");
          })
          .then(() => {
            console.log("Mikrotask 6");
          });
      });
      lösen("Mikroaufgabe 1");
    })
      .then((Daten) => {
        konsole.log(Daten);
        gib "Mikrotask 3" zurück;
      })
      .then((Daten) => {
        konsole.log(Daten);
      });

    setzeTimeout(() => {
      console.log("Makroaufgabe 2");
    }, 0);

    neues Versprechen((lösen, ablehnen) => {
      lösen("Mikroaufgabe 2");
    })
      .then((Daten, auflösen) => {
        konsole.log(Daten);
        gib "Mikrotask 4" zurück;
      })
      .then((Daten) => {
        konsole.log(Daten);
      });

    console.log("Synchronisierte Aufgabe 4");

Wie kann man es betrachten? Schauen Sie sich zuerst die erste Ebene an. Rot steht für Synchronisierung, Grün für Mikrotasks und Blau für Makrotasks.

Wir werden die Synchronisierungsaufgabe abschließen und dann sehen, dass es zwei Mikrotasks und zwei Makrotasks gibt.

Die ursprüngliche Ausführungsreihenfolge könnte wie folgt aussehen (ich drücke die Reihenfolge hier entsprechend der Seriennummer aus, bitte unterscheiden Sie sie vom einfachen Beispiel):

Doch ganz so reibungslos lief es nicht, und bei Nummer 6 war die Lage anders.

Weil während der Ausführung von Mikrotasks möglicherweise neue Mikrotasks entstehen.

Nach der Ausführung von Mikrotask 1 oben wird Mikrotask 3 nach Mikrotask 2 hinzugefügt. Das heißt, nach der Ausführung von Mikrotask 2 ist die Makrotask nicht an der Reihe. Die neue Mikrotask wird weiterhin ausgeführt, bis die Mikrotask-Warteschlange vorübergehend leer ist.

Daher werden die vier Mikrotasks in der Reihenfolge ausgeführt, in der sie der Warteschlange hinzugefügt wurden. Wenn zu diesem Zeitpunkt keine neuen Mikrotasks generiert werden, wird die Makrotask ausgeführt:

Es ist jedoch zu beachten, dass die Situation anders ist, wenn das Obige bis Nummer 5 ausgeführt wird. Nachdem die Makroaufgabe ausgeführt wurde, wird eine neue Mikroaufgabe generiert. Daher werden die beiden Makroaufgaben nicht reibungslos und kontinuierlich ausgeführt, sondern durch die eingefügte Mikroaufgabe blockiert.

(Denken Sie daran, dass, wenn sowohl Mikrotask- als auch Makrotask-Warteschlangen vorhanden sind, Mikrotasks vor Makrotasks ausgeführt werden müssen, selbst wenn sie durch die Ausführung von Makrotasks generiert werden.)

Wenn Sie die endgültige Antwort nicht verstehen, können Sie das Obige sorgfältig durchlesen:

Zusammenfassen

Dies ist das Ende dieses Artikels über die Ereigniswarteschlange des JS-Ereignisschleifens im Browser. Weitere relevante Inhalte zur Ereigniswarteschlange des JS-Ereignisschleifens finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Detaillierte Erläuterung der Ereignisschleife (Event Loop) des JavaScript-Betriebsmechanismus
  • Detaillierte Erläuterung des Ereignisschleifenmechanismus im Front-End-JS
  • Einführung in EventLoop in JavaScript
  • JS-Ereignisschleifenmechanismus Ereignisschleifen-Makrotask-Mikrotask-Prinzipanalyse
  • Analyse der mit JavaScript-Ereignisschleifen verbundenen Prinzipien

<<:  Beispielcode für die Konvertierung von MySQL-Zeilen und -Spalten

>>:  Wann ist die Verwendung von dl, dt und dd sinnvoll?

Artikel empfehlen

So aktualisieren Sie die Knotenversion unter CentOs manuell

1. Suchen Sie das entsprechende NodeJS-Paket unte...

Kommentare auf Webseiten verursachen Textüberlauf im Internet Explorer

Der experimentelle Code lautet wie folgt: </hea...

Neue Features in MySQL 8: Unsichtbare Indizes

Hintergrund Indizes sind ein zweischneidiges Schw...

HTML-Tabellen-Tag-Tutorial (7): Hintergrundfarbattribut BGCOLOR

Die Hintergrundfarbe der Tabelle kann über das At...

Verstehen Sie das CSS3-Rasterlayout in 10 Minuten

Grundlegende Einführung Im vorherigen Artikel hab...

Implementierungsbeispiel für die Message Board-Funktion von Node.js+Express

Inhaltsverzeichnis Nachrichtenbrett Erforderliche...

Detaillierte Installationsanleitung für das Cloud-Server-Pagoda-Panel

Inhaltsverzeichnis 0x01. Installieren Sie das Pag...

Implementierungsschritte zur Installation eines Redis-Containers in Docker

Inhaltsverzeichnis Redis auf Docker installieren ...