Heim > Web-Frontend > js-Tutorial > Nutzen Sie Multi-Thread in Javascript – weder über WebWorker noch über WebAssembly

Nutzen Sie Multi-Thread in Javascript – weder über WebWorker noch über WebAssembly

Mary-Kate Olsen
Freigeben: 2024-12-06 04:11:22
Original
263 Leute haben es durchsucht

Utilize Multi-Thread in Javascript - Not About WebWorkers nor WebAssembly

Es ist bekannt, dass JavaScript in einem einzelnen Thread ausgeführt wird. Dieses Konzept ist so integral, dass wir es oft namentlich nennen – den Hauptthread. Bedeutet das also, dass Ihre Multi-Core-CPU beim Ausführen von JavaScript nutzlos ist?

Nicht ganz.

JavaScript kann etwas frech sein und gemischte Nachrichten über seine Threads senden.

Aber auch ohne sich mit komplexeren Funktionen wie Web Workers und WebAssembly zu befassen, kann einfaches JavaScript Multithread-Workflows nutzen.

Um es klarzustellen: Dieser Artikel konzentriert sich auf webbrowserbasiertes JavaScript. Andere Umgebungen wie Node.js handhaben die Dinge möglicherweise anders.

Wir werden Optionen für Multi-Thread- und Multi-Thread-ähnliche Operationen in JavaScript untersuchen. Die Realität ist: Sie können und sollten Multithread-Workflows in einfachem, reinem Vanilla-JavaScript nutzen.

"Erklären!"

Gerne.

JavaScript ist eine Single-Thread-Sprache, wird aber von Webbrowsern interpretiert – und Browser sind Multi-Thread-Software.

Es gibt verschiedene Methoden, um Multithreading zu simulieren und zu nutzen, und Sie verwenden sie möglicherweise, ohne es zu merken.

Darüber hinaus verhält sich JavaScript oft auf eine Art und Weise, die den Eindruck von Multithreading erweckt, obwohl es das tatsächlich nicht ist. Es hört sich vielleicht nach Betrug an, bietet aber tatsächlich die Vorteile, die wir von Multithread-Verhalten erwarten.

Ereignisbasierte Programmierung fühlt sich multithreadig an

JavaScript ist ein ereignisbasiertes System. Wenn der Browser eine JavaScript-Datei verarbeitet, führt er den gesamten darin enthaltenen Code aus. Es ist durchaus möglich, Code zu schreiben, der nicht aufhört zu laufen – obwohl das im Allgemeinen eine schlechte Idee ist, weil es den Browser zum Absturz bringen kann.

Normalerweise richten wir Ereignis-Listener ein und warten darauf, dass etwas passiert. Zu diesem Zeitpunkt ist JavaScript völlig inaktiv. Dieses müßige Warten wäre nicht möglich, ohne etwas Arbeit aus dem Haupt-Thread auszulagern.

Ereignisse selbst sind nicht multithreaded, aber das Warten und Überprüfen auf Ereignisse wird vom Browser und nicht von JavaScript übernommen. Dieser Prozess wird vom Hauptthread ausgelagert.

Asynchrone Funktionen und Multithreading

Funktionen wie setTimeout und setInterval gibt es schon seit vielen Jahren bei uns. Sie entlasten den Hauptthread von der Wartezeit.

Lassen Sie uns die Funktionsweise vereinfachen. In niedrigeren Sprachen werden Timer und Warten oft durch die ständige Überprüfung implementiert: „Ist es schon Zeit?“ Stellen Sie sich eine while()-Schleife vor, die die verstrichene Zeit überprüft und zum richtigen Zeitpunkt fortfährt. Moderne Ansätze verwenden möglicherweise CPU-Interrupts, um ein Verstopfen des CPU-Threads zu vermeiden.

Wenn Sie jedoch setTimeout oder setInterval in JavaScript verwenden, ist die Sprache während des Wartens völlig inaktiv, was wiederum bedeutet, dass das Warten irgendwie außerhalb des Hauptthreads verarbeitet wird.

Fetch und andere asynchrone APIs

Heutzutage erhalten wir immer mehr asynchrone Funktionen und APIs von Browsern. Die Fetch-API ist ein bekanntes Beispiel. Auch neuere APIs, wie die Clipboard-API, sind asynchron.

Das bedeutet, dass Sie den Browser auffordern, eine Aktion auszuführen, und dieser den Haupt-Thread von JavaScript freigibt (oder ihm die Verarbeitung anderer Dinge ermöglicht – mehr dazu später) und Sie benachrichtigt (durch die Verarbeitung des folgenden Codes), wenn die Aktion abgeschlossen ist.

Asynchron vs. Multithreaded

Asynchron bedeutet nicht unbedingt Multithreading – nicht immer, nicht direkt. Einfach das Wort „async“ vor eine Funktion zu setzen, bringt dir nichts.

Es gibt zwei Schlüsselkomponenten dafür, wie JavaScript mit asynchronem Verhalten umgeht:

1. Rückrufwarteschlange und Ereignisschleife

Stellen Sie sich die Rückrufwarteschlange als eine Reihe von Funktionen vor, die darauf warten, ausgeführt zu werden. Diese Funktionen werden nacheinander im Hauptthread ausgeführt. Wenn ein asynchroner Vorgang abgeschlossen ist – sei es ein Ereignis, eine Zeitüberschreitung oder ein abgeschlossener Abruf – wird sein Rückruf in diese Warteschlange gestellt.

Die Ereignisschleife ist dafür verantwortlich, Rückrufe aus der Warteschlange in den Aufrufstapel zu verschieben, wenn der Aufrufstapel leer ist.

2. Vom Browser verarbeitete Funktionen

Der Webbrowser übernimmt die Kontrolle über bestimmte Vorgänge und erstellt möglicherweise neue Threads für diese – dazu gehören Aktionen wie fetch oder setTimeout. JavaScript muss diese Threads nicht verwalten. Wenn der asynchrone Vorgang abgeschlossen ist, stellt der Browser den entsprechenden Rückruf in die Rückrufwarteschlange und JavaScript setzt die Ausführung von dort aus fort.

Beachten Sie diesen Code:

console.log('Start');

setTimeout(() => {
  console.log('This is asynchronous');
});

console.log('End');
Nach dem Login kopieren

Ausgabe:

Start
End
This is asynchronous
Nach dem Login kopieren

Das passiert:

  • „Start“ wird protokolliert.
  • setTimeout wird ohne Timeout-Parameter aufgerufen und ist daher standardmäßig auf 0 Millisekunden eingestellt. Der Rückruf wird zur Ausführung an den Browser gesendet, nachdem der aktuelle Aufrufstapel gelöscht ist.
  • „Ende“ wird protokolliert.
  • Der Hauptthread ist jetzt frei und die Ereignisschleife überprüft die Rückrufwarteschlange.
  • Die Rückruffunktion von setTimeout wird in den Aufrufstapel verschoben.
  • „Dies ist asynchron“ wird protokolliert.

Beachten Sie, dass setTimeout der Timeout-Parameter fehlt. Dies ist eine gängige Technik, um die Ausführung von Code mit niedrigerer Priorität zu verzögern – verarbeiten Sie zuerst alles andere, und führen Sie dann die Sache mit der „niedrigeren Priorität“ aus.

Dadurch wird die Funktion innerhalb von setTimeout sofort in die Rückrufwarteschlange gestellt und bei der ersten Gelegenheit ausgeführt, wenn der Hauptthread inaktiv ist.

Der Sonderfall von requestAnimationFrame

requestAnimationFrame ist eine Browser-API, die dem Browser mitteilt, dass Sie Code ausführen möchten, kurz bevor er die Ansicht berechnet und aktualisiert (stellen Sie sich das in Videospielen als Bilder pro Sekunde vor).

Aus irgendeinem Grund denken Webentwickler nicht an Repaints und FPS, aber so funktioniert es.

Es ist von Natur aus asynchron (jedoch nicht multithreaded).

Die Verwendung von setTimeout ohne Angabe einer Zeit wurde vor der Einführung von requestAnimationFrame oft für ähnliche Zwecke verwendet, obwohl es bei weitem nicht so nützlich war (einfach besser als nichts).

Diese Funktion stellt Ihren Code in eine Warteschlange in einem speziellen Stapel. Kurz vor dem Rendern eines neuen Frames (dem Repaint) führt der Browser diesen Code in der Warteschlange aus. Es ist perfekt, um Änderungen am DOM, HTML oder CSS vorzunehmen (und bitte nur diese, ich verbiete Ihnen, dort Berechnungen durchzuführen!).

Echte Multi-Threading-Optionen

Auch wenn es in diesem Artikel nicht um sie geht, ist es erwähnenswert, dass Sie echte Multithread-Operationen erreichen können, indem Sie Web Worker und WebAssembly verwenden. Damit können Sie Skripte in Hintergrundthreads ausführen. Sie können das DOM nicht direkt manipulieren, sind aber für die Verarbeitung schwerer Aufgaben (Matrixberechnungen, irgendjemand?) von unschätzbarem Wert. Dieser Ansatz wird häufig in HTML5-basierten Spielen verwendet – den komplexeren, nicht nur Tic-Tac-Toe.

Letzte Worte

Wenn JavaScript isoliert ist, bleibt es Single-Threaded. In der realen Welt handelt es sich jedoch um eine interpretierte Sprache, die in Multithread-Umgebungen von Webbrowsern ausgeführt wird. Wenn Ihr Dolmetscher Ihnen eine helfende Hand anbietet, nehmen Sie sie an und nutzen Sie sie.

Dieser Artikel deckt viel ab – Grundwissen, einfache Erklärungen und mehr. Aber so ist die Entwicklung oft – alles ist miteinander verbunden. Deshalb betrachte ich gerne das Gesamtbild; Manchmal ist eine detaillierte Fokussierung nicht die Lösung eines Problems.


Hat Ihnen Async schon einmal Alpträume beim Debuggen bereitet?
Das habe ich auf jeden Fall – vor einigen Jahren war es keine große Sache, Stacks mit Fehlern zu bekommen.

Das obige ist der detaillierte Inhalt vonNutzen Sie Multi-Thread in Javascript – weder über WebWorker noch über WebAssembly. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage