JavaScript-Einzelthread und asynchrone Details

JavaScript-Einzelthread und asynchrone Details

Vorwort:

Angesichts der single threaded und asynchronous Natur von JavaScript fragen sich viele Studenten: Ist das nicht ein Widerspruch? Tatsächlich können Single-Threaded und Asynchronität nicht gleichzeitig Merkmale einer Sprache sein. js hat sich dafür entschieden, eine Single-Thread-Sprache zu sein, sodass es selbst nicht asynchron sein kann, aber die Hostumgebung von js (wie Browser, Node ) ist Multi-Threaded, und die Hostumgebung sorgt dafür, dass js in gewisser Weise asynchrone Eigenschaften hat (ereignisgesteuert, was weiter unten erläutert wird). Wenn Sie nach unten schauen, werden Sie feststellen, wie einfach und effizient der JS-Mechanismus ist!

Browser:

js ist eine Single-Thread-Sprache. Der Browser weist js nur einen Hauptthread zu, um Aufgaben (Funktionen) auszuführen, aber es kann immer nur eine Aufgabe gleichzeitig ausgeführt werden. Diese Aufgaben bilden eine Aufgabenwarteschlange, die darauf wartet, ausgeführt zu werden. Einige Aufgaben auf dem Frontend sind jedoch sehr zeitaufwändig, z. B. Netzwerkanforderungen, Timer und Ereignisüberwachung. Wenn sie wie andere Aufgaben in der Warteschlange warten müssen, ist die Ausführungseffizienz sehr gering und kann sogar zum Einfrieren der Seite führen. Daher öffnet der Browser zusätzliche Threads für diese zeitaufwändigen Aufgaben, hauptsächlich HTTP-Anforderungsthreads, Browser-Timing-Trigger und Browser-Event-Trigger-Threads. Diese Aufgaben sind asynchron. Das folgende Diagramm veranschaulicht den Haupt-Thread eines Browsers.

1. Aufgabenwarteschlange

Ich habe gerade erwähnt, dass der Browser einen separaten Thread für asynchrone Aufgaben wie Netzwerkanforderungen öffnet. Die Frage ist also, woher weiß der Hauptthread, wann diese asynchronen Aufgaben abgeschlossen sind? Die Antwort ist die Rückruffunktion. Das gesamte Programm ist ereignisgesteuert und jedes Ereignis wird an eine entsprechende Rückruffunktion gebunden. Beispielsweise gibt es einen Codeabschnitt, der einen Timer einstellt.

setzeTimeout(Funktion(){
    console.log(Zeit ist abgelaufen);
}, 50);


Wenn dieser Code ausgeführt wird, führt der Browser den Zeitvorgang asynchron aus. Wenn 50 ms erreicht sind, wird das Zeitereignis ausgelöst. Zu diesem Zeitpunkt wird die Rückruffunktion in die Aufgabenwarteschlange gestellt. Das gesamte Programm wird von solchen Ereignissen bestimmt.
Daher war js schon immer ein Single-Thread-System und die Asynchronität wird vom Browser implementiert.

Zurück zum Hauptthread:

js hat eine Aufgabe ausgeführt, nämlich Aufgaben aus der Aufgabenwarteschlange zu extrahieren und sie zur Ausführung in den Hauptthread zu stellen. Lassen Sie uns einen genaueren Blick darauf werfen.

Vergleichen wir die Konzepte, die wir gerade gelernt haben, mit dem Diagramm. Die Threads, die der Browser separat für die oben genannten asynchronen Aufgaben öffnet, können einheitlich als WebAPIs verstanden werden. Die oben erwähnte Aufgabenwarteschlange ist callback queue . Der Hauptthread, über den wir sprechen, ist der Teil, der aus gepunkteten Linien besteht. Der heap und stack bilden zusammen den Hauptthread von js. Die Ausführung von Funktionen wird durch Pushen und Popen des Stapels erreicht. Beispielsweise gibt es im Diagramm eine Funktion foo(). Der Hauptthread schiebt sie in den Stapel. Beim Ausführen des Funktionskörpers stellt er fest, dass die obigen Funktionen ausgeführt werden müssen, sodass diese Funktionen erneut in den Stapel geschoben werden. Nachdem die Funktion ausgeführt wurde, wird die Funktion vom Stapel entfernt. Wenn der Stapel leer ist, bedeutet dies, dass eine Aufgabe abgeschlossen wurde. Zu diesem Zeitpunkt wird die nächste Aufgabe in callback queue gefunden und in den Stapel verschoben ( dieser Suchvorgang wird als Ereignisschleife bezeichnet, da er immer eine Schleife durchläuft, um festzustellen, ob sich Aufgaben in der Aufgabenwarteschlange befinden ).

2. Um einige verwirrende Probleme zu erklären

1. Was ist setTimeout(f1,0)?

Die größte Frage zu dieser Aussage ist: Wird f1 sofort ausgeführt? Die Antwort lautet nicht unbedingt, da es davon abhängt, ob der Befehl im Hauptthread ausgeführt wurde, wie im folgenden Code gezeigt:

setzeTimeout(Funktion(){
konsole.log(1);
},0);
konsole.log(2);

2. Ist die Ajax-Anfrage asynchron?

Nachdem wir den obigen Inhalt verstanden haben, wissen wir, dass ajax -Anfragen asynchron sind. Wenn die Anfrage abgeschlossen ist, wird das Anfrageabschlussereignis ausgelöst und dann wird die Rückruffunktion in callback queue gestellt. Wenn der Hauptthread die Rückruffunktion ausführt, handelt es sich immer noch um einen Single-Thread.

3. Der Interface-Rendering-Thread ist ein separater Thread

Der Thread zum Rendern der Schnittstelle ist ein separat geöffneter Thread. Bedeutet das, dass die Schnittstelle sofort neu gerendert wird, sobald sich das DOM ändert?

Wenn die Schnittstelle sofort neu gerendert wird, sobald sich das DOM ändert, ist die Effizienz zwangsläufig sehr gering. Daher legt der Browsermechanismus fest, dass sich der Schnittstellen-Rendering-Thread und der Hauptthread gegenseitig ausschließen. Wenn der Hauptthread Aufgaben ausführt, befindet sich der Browser-Rendering-Thread in einem angehaltenen Zustand.

3. So verwenden Sie den asynchronen Mechanismus des Browsers

Wir wissen bereits, dass js immer in einem einzigen Thread ausgeführt wurde und der Browser separate Threads für mehrere offensichtlich zeitaufwändige Aufgaben eingerichtet hat, um die zeitaufwändigen Probleme zu lösen. Zusätzlich zu diesen offensichtlichen zeitaufwändigen Problemen kann es jedoch auch in den Programmen, die wir selbst schreiben, zeitaufwändige Funktionen geben. Wie gehen wir mit dieser Situation um? Wir können natürlich selbst keinen separaten Thread öffnen, aber wir können die vom Browser geöffneten Fenster verwenden. Der Browser-Timer-Thread und der Event-Trigger-Thread sind einfach zu verwenden, aber der Netzwerkanforderungs-Thread ist für uns nicht geeignet. Schauen wir uns das genauer an:

Angenommen, die zeitaufwändige Funktion ist f1 und f1 ist die Vorgängeraufgabe von f2.

Verwenden Sie den Timer, um den Thread auszulösen:

Funktion f1(Rückruf){
setzeTimeout(Funktion(){
    // f1 Code-Rückruf();
},0);
}
f1(f2);

Dieses Schreibverfahren weist einen hohen Kopplungsgrad auf.

Verwenden Sie Ereignisse, um Threads auszulösen:

$f1.on('custom',f2); //Hier wird das Bindungsereignis als jQuery-Funktion f1(){ geschrieben.
setzeTimeout(Funktion(){
    // Code für f1$f1.trigger('custom');
},0);
}


Diese Methode entkoppelt Methode 1 durch das Binden benutzerdefinierter Ereignisse, sodass verschiedene Rückruffunktionen durch das Binden verschiedener Ereignisse implementiert werden können. Wird diese Methode jedoch zu häufig angewendet, wird das Programm schwer lesbar.

4. Vorteile der Asynchronität und geeignete Szenarien

Vorteile der Asynchronität:

Vergleichen wir Synchronisation und Asynchronität anhand eines Beispiels. Angenommen, es gibt vier Aufgaben (Nummer 1, 2, 3 und 4) und ihre Ausführungszeit beträgt 10 ms. Aufgabe 2 ist die Vorgängeraufgabe von Aufgabe 3 und Aufgabe 2 erfordert eine Reaktionszeit von 20 ms. Lassen Sie uns unten einen Vergleich durchführen, und Sie erfahren, wie Sie nicht blockierende E/A implementieren.

Geeignet für:

Es ist ersichtlich, dass sich js, eine Sprache mit Single-Thread-, asynchronen und ereignisgesteuerten Eigenschaften, sehr gut eignet, wenn unser Programm eine große Anzahl von E/A-Vorgängen und Benutzeranforderungen erfordert. Im Vergleich zu Multithread-Sprachen muss es nicht zu viel System-Overhead verbrauchen und muss auch keine Energie für die Verwaltung von Multithreads aufwenden. Im Vergleich zu synchronen Ausführungssprachen ermöglichen die asynchronen und ereignisgesteuerten Mechanismen der Hostumgebung die Implementierung von nicht blockierenden E/A. Sie sollten also wissen, für welche Szenarien es geeignet ist!

Dies ist das Ende dieses ausführlichen Artikels über Single-Threaded und Asynchrones JavaScript . Weitere relevante Inhalte zu Single-Threaded und Asynchronem JavaScript 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:
  • Eine kurze Diskussion über die drei Hauptprobleme von JS: Asynchronität und Single-Thread
  • Detaillierte Erläuterung der asynchronen Prozessimplementierung in Single-Thread-JavaScript
  • Analysieren Sie die Eigenschaften des asynchronen IO-Rückrufs mit einem Thread in JS
  • Die drei Berge von JavaScript: Single Thread und Asynchron

<<:  Grafisches Tutorial zur Installation und Konfiguration von MySQL 8.0.22 winx64

>>:  Ursachen und Lösungen für den Nginx 502 Bad Gateway-Fehler

Artikel empfehlen

js-Version zur Realisierung der Rechnerfunktion

In diesem Artikelbeispiel wird der spezifische Co...

Tutorial zu HTML-Tabellen-Tags (8): Hintergrundbild-Attribut BACKGROUND

Legen Sie ein Hintergrundbild für die Tabelle fes...

Attribute im Vue V-For-Loop-Objekt

Inhaltsverzeichnis 1. Werte innerhalb von Schleif...

CSS3-Kategoriemenüeffekt

Die CSS3-Kategoriemenüeffekte sind wie folgt: HTM...

Detaillierte Erklärung der MySQL-Datumsadditions- und -subtraktionsfunktionen

1. addtime() Füge die angegebene Anzahl Sekunden ...

Webdatenspeicherung: Cookie, UserData, SessionStorage, WebSqlDatabase

Plätzchen Dies ist eine Standardmethode zum Speic...

Wie kompliziert ist die Priorität von CSS-Stilen?

Gestern Abend habe ich mir eine Interviewfrage ang...

Vollständige Analyse des Vue-Diff-Algorithmus

Inhaltsverzeichnis Vorwort Vue-Aktualisierungsans...

JavaScript ist unzuverlässig undefiniert

undefined Wenn wir in JavaScript feststellen möch...

Reagieren Sie auf die Konstruktionsreihenfolge verschachtelter Komponenten

Inhaltsverzeichnis Auf der offiziellen React-Webs...

Detaillierte Erklärung der regulären Ausdrücke von Nginx

Nginx (Engine x) ist ein leistungsstarker HTTP- u...

So verwenden Sie Nginx, um domänenübergreifende Front-End-Probleme zu lösen

Vorwort Bei der Entwicklung statischer Seiten, wi...

So erstellen Sie SonarQube mit Docker

Inhaltsverzeichnis 1. Docker installieren 2. Sona...