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

Proxy realisiert das Prinzip der bidirektionalen Bindung von Vue3-Daten

Inhaltsverzeichnis 1. Vorteile von Proxy gegenübe...

Erläuterung der JavaScript-Funktionssyntax

Inhaltsverzeichnis 1. Gewöhnliche Funktionen 2. P...

So ändern Sie das Passwort in MySQL 5.7.18

So ändern Sie das Passwort in MySQL 5.7.18: 1. Fa...

Verwendung des offiziellen MySQL-Exporttools mysqlpump

Inhaltsverzeichnis Einführung Anweisungen Tatsäch...

So verwenden Sie Indizes zur Optimierung von MySQL ORDER BY-Anweisungen

Tabelle erstellen und Index erstellen Tabelle tbl...

Installieren und Bereitstellen von Java8 und MySQL unter CentOS7

Im Allgemeinen werden Java-Lernprogramme und Bere...

Grafisches Tutorial zur Installation und Konfiguration von MySQL 5.7.17 winx64

Ich habe die vorherigen Hinweise zur Installation...

Mehrere Grundsätze für die Produktdesign-Referenz auf Websites

In der folgenden Analyse geht es um Produktdesign...

Zusammenfassung der Wissenspunkte zum Ereignismodul in Node.js

Durch das Studium und die Anwendung von Node wiss...

Eine einfache Möglichkeit, Desktop-Exe-Programme auf einer Webseite aufzurufen

Dieser Artikel stellt hauptsächlich vor, wie Deskt...