Dieser Artikel vermittelt Ihnen Wissen über unseren JavaScript-Single-Thread. Warum kann JavaScript einen Timer und eine Funktion gleichzeitig ausführen?
1. Prozesse und Threads Planung im System, die die Grundlage der Betriebssystemstruktur bildet. In der modernen, für Threads konzipierten Computerarchitektur sind Prozesse Container für Threads. Ein Programm ist eine Beschreibung von Anweisungen, Daten und deren Organisation, und ein Prozess ist die Einheit des Programms. Es handelt sich um eine laufende Aktivität eines Programms in einem Computer für einen bestimmten Datensatz. Es ist die Grundeinheit der Ressourcenzuweisung und -planung im System und die Grundlage der Betriebssystemstruktur. Ein Programm ist eine Beschreibung von Anweisungen, Daten und deren Organisation, und ein Prozess ist die Einheit des Programms. Wir vergleichen den Prozess hier mit der Werkstatt einer Fabrik, die eine einzelne Aufgabe darstellt, die die CPU bewältigen kann. Zu jedem Zeitpunkt führt die CPU immer einen Prozess aus, und andere Prozesse befinden sich in einem nicht ausgeführten Zustand.
1.2 Thread
ist die kleinste Einheit, die das Betriebssystem zur Berechnungsplanung durchführen kann. Es wird in den Prozess eingebunden und ist die eigentliche Bedieneinheit im Prozess. Ein Thread bezieht sich auf einen einzelnen sequenziellen Kontrollfluss in einem Prozess. In einem Prozess können mehrere Threads gleichzeitig ausgeführt werden, und jeder Thread führt parallel unterschiedliche Aufgaben aus.
Hier werden Threads mit Arbeitern in einer Werkstatt verglichen, das heißt, in einer Werkstatt können mehrere Arbeiter zusammenarbeiten, um eine Aufgabe zu erledigen.
2. Multithread-Browser
Unter der Kontrolle des Kernels kooperiert jeder Thread miteinander, um die Synchronisation aufrechtzuerhalten:
GUI-Rendering-Thread
JavaScript-Engine-Thread
Event-Trigger-Thread
Timed-Trigger-Thread
Asynchroner HTTP-Anfrage-Thread
2.1 Lassen Sie uns hier über den Ausführungsmechanismus von JS sprechen
Da JavaScript Single-Threaded ist (es gibt immer nur einen JS-Thread, der das JavaScript-Programm auf einer Tab-Seite ausführt).
Wir müssen uns also auf die Aufgabenwarteschlange verlassen, um JavaScript-Code auszuführen.
Die JS-Engine wartet immer auf das Eintreffen von Aufgaben in der Aufgabenwarteschlange und führt die Aufgaben dann aus. Natürlich ist es kein Problem, Synchronisierungsaufgaben auf diese Weise auszuführen. Wir stellen die Aufgaben in die Aufgabenwarteschlange und führen sie einzeln aus. Die Logik ist sehr klar. Wenn wir jedoch eine Anfrage an den Hintergrund senden, kann die Zeit zwischen Senden und Empfangen eine Sekunde dauern. Wenn wir fünfmal eine Anfrage stellen, dann fünf Sekunden warten. Die Anzeige entspricht nicht unseren Anforderungen, daher benötigen wir eine asynchrone Aufgabe, um dieses Problem zu lösen.
2.2 Synchrone Aufgaben und asynchrone AufgabenSynchrone Aufgaben beziehen sich auf Aufgaben, die zur Ausführung im Hauptthread in die Warteschlange gestellt werden. Erst wenn die vorherige Aufgabe ausgeführt wird, kann der Rendervorgang fortgesetzt werden Website, Beispielsweise ist das Rendern von Elementen tatsächlich eine synchrone Aufgabe.
Asynchrone Aufgaben beziehen sich auf Aufgaben, die nicht in den Hauptthread, sondern nur dann in die Aufgabenwarteschlange gelangen, wenn die Aufgabenwarteschlange den Hauptthread benachrichtigt, dass eine asynchrone Aufgabe ausgeführt werden kann Wird die Aufgabe in den Hauptthread aufgenommen, ist das Laden von Bildern und Musik tatsächlich eine asynchrone Aufgabe.
Jeder muss ein konkreteres Verständnis von Event Loop haben. Ich werde hier nicht auf Details eingehen. Wenn Sie es nicht verstehen, können Sie es mir sagen und ich werde es noch einmal erklären.
3. Dieser Artikel konzentriert sich auf die wichtigsten Punkte – Sie können ihn direkt lesenAber haben Sie Fragen zur Aufgabenwarteschlange? Ist das ein Objekt? Ist es ein Array? Nach meiner Logik führt unser JavaScript-Hauptthread synchrone Funktionen aus, und asynchrone Funktionen können in die Aufgabenwarteschlange gestellt werden. Wenn wir mit der Ausführung der synchronen Aufgabe fertig sind, schieben Sie dieses Objekt (Aufgabenwarteschlange) in die Hauptwarteschlange Im Thread ist alles in Ordnung, aber es ist nicht das, was ich gedacht habe.
Die Aufgabenwarteschlange von Evnet Loop wird im ereignisauslösenden Thread des Browsers platziert. Wenn die JS-Engine eine asynchrone Funktion ausführt, platziert sie die asynchrone Aufgabe im ereignisauslösenden Thread Der ereignisauslösende Thread fügt die asynchrone Aufgabe am Ende der Warteschlange des Hauptthreads in der JS-Engine hinzu und wartet auf die Ausführung.
Unterscheidet es sich von dem Single-Threaded-JavaScript, das wir uns vorgestellt haben? Nun, es ist wirklich nicht dasselbe, daher ist die endgültige Schlussfolgerung, dass es sich bei der Aufgabenwarteschlange, über die wir sprechen, tatsächlich um einen Thread handelt. Wenn wir dann auf den Timer zurückkommen, über den wir gerade am Anfang gesprochen haben, können Sie im Grunde davon ausgehen, dass er vom Timer-Thread gesteuert wird.
Da es sich bei JavaScript um einen Single-Thread handelt, beeinträchtigt es die Genauigkeit des Timings, wenn es sich in einem blockierten Thread-Status befindet. Daher ist es erforderlich, einen separaten Thread für das Timing zu öffnen.
Bei Verwendung von setTimeout oder setInterval ist ein Timer-Thread-Timing erforderlich. Nach Abschluss des Timings wird das spezifische Ereignis in die Ereigniswarteschlange verschoben.
4. Fazit
Wir sagen also, dass JavaScript Single-Threaded ist, auch wenn der King of Heaven kommt, aber unsere Ereignisschleife und unser Timer sind in anderen Threads platziert.
5. V8-Engine – Erweiterung
V8-Engine ist eine JavaScript-Engine-Implementierung, die ursprünglich von einigen Sprachexperten entworfen und später von Google erworben und dann als Open Source bereitgestellt wurde.
V8 wird mit C++ entwickelt. Im Gegensatz zu anderen JavaScript-Engines, die es in Bytecode konvertieren oder zur Ausführung interpretieren, kompiliert V8 es in nativen Maschinencode (IA-32-, x86-64-, ARM- oder MIPS-CPUs). , und Methoden wie Inline-Caching werden verwendet, um die Leistung zu verbessern.
Mit diesen Funktionen laufen JavaScript-Programme genauso schnell wie Binärprogramme unter der V8-Engine. V8 unterstützt viele Betriebssysteme wie Windows, Linux, Android usw. sowie andere Hardwarearchitekturen wie IA32, X64, ARM usw. und verfügt über gute Portabilität und plattformübergreifende Funktionen.
5.1 Arbeitsablauf
Der Prozess der Ausführung von JavaScript durch die V8-Engine besteht aus zwei Hauptphasen: Kompilierung und Ausführung. Im Gegensatz zu C++, das vor der Ausführung vollständig kompiliert wird, muss JavaScript kompiliert und ausgeführt werden, wenn der Benutzer es verwendet. In V8 wird JavaScript-bezogener Code nicht auf einmal kompiliert, sondern erst dann, wenn bestimmte Codes ausgeführt werden müssen, was die Reaktionszeit verbessert und den Zeitaufwand reduziert. In der V8-Engine wird der Quellcode zunächst vom Parser in einen abstrakten Syntaxbaum (AST) konvertiert, und dann wird der vollständige Codegenerator des JIT-Compilers verwendet, um direkt lokalen ausführbaren Code aus dem AST zu generieren. Dieser Prozess unterscheidet sich von JAVAs erster Generation von Bytecode oder Zwischendarstellung, wodurch die Konvertierungszeit von AST in Bytecode verkürzt und die Codeausführungsgeschwindigkeit verbessert wird. Aufgrund des fehlenden Zwischenprozesses der Konvertierung in Bytecode ist jedoch die Möglichkeit zur Optimierung des Codes geringer.
Die von der V8-Engine beim Kompilieren von lokalem Code verwendeten Hauptklassen sind wie folgt:
Skript: Stellt JavaScript-Code dar, der Quellcode und lokalen Code enthält, der nach der Kompilierung generiert wird, also den Kompilierungseintrag und den laufenden Eintrag
Compiler: Compiler-Klasse, Hilfsgruppe Skriptklasse zum Kompilieren und Generieren von Code, Aufruf des Interpreters (Parser) zum Generieren von AST und vollständigem Codegenerator, Konvertieren von AST in lokalen Code;
AstNode: abstrakter Syntaxbaum Die Knotenklasse ist die Basisklasse für alle anderen Knoten und enthält später verschiedene lokale Codes für verschiedene Unterklassen
Das obige ist der detaillierte Inhalt vonVerstehen Sie den einzelnen Thread von JavaScript wirklich?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!