Heim > Web-Frontend > js-Tutorial > JavaScript-Engine

JavaScript-Engine

WBOY
Freigeben: 2024-09-01 21:13:37
Original
843 Leute haben es durchsucht

JavaScript Engine

JS-Engine:

  • Programm, das JS-Code ausführt. Ex. Googles V8.
  • V8 unterstützt Chrome, Node.js
  • Andere Browser haben ihre eigene JS Engine.

JS Engine besteht aus 2 Teilen:

  1. Aufrufstapel: Wo unser Code mithilfe des Ausführungskontexts ausgeführt wird.
  2. Heap: Unstrukturierter Speicherpool, der zum Speichern von Objekten verwendet wird.

Jedes C/R-Programm muss in Maschinencode konvertiert werden. Erfolgt über zwei Prozesse:

1. Kompilierung: Der gesamte Code wird auf einmal in Maschinencode umgewandelt und in eine Binärdatei geschrieben, die von einem Computer ausgeführt werden kann.

Quellcode – (kompiliert) –> Binärcode[Portable File] -(ausgeführt)-> Pgm-Lauf
Die Ausführung kann erst lange nach der Kompilierung erfolgen.

2. Interpretation: Der Interpreter geht den Quellcode durch und führt ihn Zeile für Zeile aus.

Quellcode - (Zeile für Zeile ausführen) -> Pgm-Lauf

  • Hier muss der Code noch in Maschinencode umgewandelt werden.
  • Sie sind im Vergleich zu kompilierten L/Gs viel langsamer.

3. JIT, d. h. Just-in-Time-Zusammenstellung:

  • Modern JS Engine ist eine Mischung aus Kompilierung und Interpretation, um es schnell zu machen.
  • Der gesamte Code wird auf einmal in Maschinencode umgewandelt und dann sofort ausgeführt. Quellcode – (kompiliert) –> Maschinencode -(ausgeführt)-> Pgm-Lauf
  • Es gibt keine tragbare Zwischendatei zum Ausführen.
  • Die Ausführung erfolgt unmittelbar nach der Kompilierung.
  • Daher ist JS aufgrund dieser Technik jetzt viel schneller als interpretierte L/Gs.

Kompilierungsprozess in JS:

Schritt 1. Parsen:

  • Unser Code wird geparst, d. h. von der JS-Engine in AST oder Abstract Syntax Tree eingelesen.
  • Funktioniert durch Aufteilen des Codes in einen Baum basierend auf Schlüsselwörtern wie const, let, function usw., die für das L/G von Bedeutung sind.
  • Dann wird der Code strukturiert in einem Baum gespeichert.
  • Überprüfen Sie außerdem, ob Syntaxfehler vorliegen.
  • AST hat nichts mit dem DOM-Baum zu tun. AST ist lediglich eine Darstellung unseres Codes innerhalb der JS Engine.

Schritt 2, 3[kombiniert]: Kompilierung + Ausführung

  • AST wird kompiliert und unmittelbar danach mit JIT ausgeführt.
  • Die Ausführung erfolgt im Aufrufstapel.
  • Modernes JS verfügt über clevere Optimierungsstrategien, d. h. sie erstellen zu Beginn schnell eine nicht optimierte Version des Maschinencodes, um so schnell wie möglich mit der Ausführung zu beginnen.
  • Im Hintergrund wird dieser Code während einer bereits laufenden PGM-Ausführung erneut kompiliert.
  • Wird in mehreren Iterationen durchgeführt und nach jeder Optimierung wird der nicht optimierte Code durch neu optimierten Code ausgetauscht, ohne dass die Codeausführung jemals gestoppt wird. Das macht V8 so schnell.
  • All dieses Parsen, Kompilieren und Ausführen findet in einem speziellen Thread innerhalb der JS Engine statt, auf den wir mit unserem Code nicht zugreifen können, der völlig getrennt vom Hauptthread ist, der unseren Code mithilfe des Aufrufstapels ausführt.
  • JS wird nicht mehr nur l/g interpretiert. Es verfügt über eine JIT-Kompilierung, die es viel schneller macht als interpretierte l/gs.

JS-Laufzeit = JS-Engine + Web-APIs + C/B-Warteschlange

  • JS-Laufzeit: Container mit allen Dingen, die wir zur Verwendung von JS benötigen.
  • Das Herzstück jeder JS-Laufzeit ist die JS-Engine.
  • Ohne JS Engine gibt es keine Laufzeit, also überhaupt kein JS.
  • JS Engine allein reicht nicht aus, wir benötigen Zugriff auf Web-APIs wie DOM, Fetch, Timer usw.
  • Web-APIs: Funktionalität, die der Engine von der Laufzeit bereitgestellt wird, aber nicht Teil der JS-Engine ist. Ex. Fensterobjekt im Browser, globales Objekt im Knoten.
  • Callback Queue ist eine Datenstruktur, die alle zur Ausführung bereiten Funktionen enthält. Ex. Klick, Timer, Daten usw.
  • DOM-Ereignishandler-FNS werden auch als Callback-FNS bezeichnet.
  • Wenn der Call-Stack leer ist, wird der Callback-FN zur Ausführung von der C/B-Warteschlange in den Call-Stack verschoben.
  • Die kontinuierliche Überprüfung und Verschiebung wird von der Ereignisschleife durchgeführt.
  • Ereignisschleife ist etwas, das JS ein nicht blockierendes Parallelitätsmodell ermöglicht.
  • Für den Knoten verfügen wir nicht über Web-APIs, die vom Browser bereitgestellt werden. Wir haben etwas namens C++-Bindungen und Thread-Pool.

Wie JS-Code auf dem Call Stack ausgeführt wird

  • JS verfügt über einen einzelnen Ausführungsthread und kann daher jeweils nur etwas ausführen. Daher kein Multiasking in JS.
  • APIs werden von der Umgebung bereitgestellt, nicht jedoch vom Teil der Sprache. Ex. Web-APIs wie Timer, Fetch, DOM, Geolocation usw.
  • Rückrufwarteschlange: Bereit zur Ausführung von Rückruf-FNS, die an ein eingetretenes Ereignis angehängt sind.
  • Immer wenn der Aufrufstapel leer ist, überträgt die Ereignisschleife den Rückruf vom Rückruf zur Warteschlange zum Aufrufstapel zur Ausführung.
  • Die Ereignisschleife ist daher ein wesentlicher Bestandteil, der asynchrones Verhalten in JS ermöglicht.
  • Parallelitätsmodell: Wie ein L/G mit mehreren Dingen umgeht, die gleichzeitig passieren.
  • Wesentliche Teile der JS-Laufzeit:
  • Anrufstapel
  • Web-APIs
  • Rückrufwarteschlange
  • Ereignisschleife
  • Alles, was mit DOM zu tun hat, ist Teil von Web-APIs, nicht JS.
  • Das Laden von Bildern erfolgt asynchron. Wäre es synchron gewesen, hätte es blockiert, d. h. nicht im Hauptthread, sondern in der Web-API-Umgebung.
  • Alle Ereignis-Listener, .then() usw. funktionieren in der WEb-API-Umgebung und nicht im Aufrufstapel.
  • Rückruf-FNS werden in die Rückrufwarteschlange gestellt und warten darauf, dass sie im Aufrufstapel ausgeführt werden.
  • Die Rückrufwarteschlange ist wie eine Aufgabenliste, die ein Anrufstapel abarbeiten muss.
  • Die angegebene Dauer ist die Mindestverzögerung vor der Ausführung und nicht die Ausführungszeit.
  • Die Rückrufwarteschlange enthält auch Rückrufe, die von DOM-Ereignissen, Klicks, Tastendrücken usw. stammen. DOM-Ereignisse sind kein asynchrones Verhalten, sondern verwenden für ihre Ausführung die Rückrufwarteschlange.
  • Die Ereignisschleife überprüft die Rückrufwarteschlange so lange, bis sie leer ist. Jeder im Aufrufstapel platzierte Rückruf wird als Ereignisschleifen-Tick bezeichnet.
  • Ereignisschleife orchestriert die gesamte JS-Laufzeit.
  • JS hat selbst kein Zeitgefühl, da Async-Code nicht in der Engine ausgeführt wird. Es ist die Laufzeit, die das asynchrone Verhalten verwaltet, und die Ereignisschleife, die entscheidet, welcher Rückruf ausgeführt werden soll.
  • Engine oder Call Stack führt einfach den ihr zugewiesenen Code aus.
  • Wenn ein Bild geladen werden soll, wartet der Ereignis-Listener in der Web-APIs-Umgebung weiter, bis das Ladeereignis ausgelöst wird. Wenn es ausgelöst wird, geht nur es als Rückruf-FN in die Rückrufwarteschlange und wartet darauf, dass es im Aufrufstapel ausgeführt wird.

Mikrotask-Warteschlange:

  • Rückrufe von Promises gelangen nicht in die Rückrufwarteschlange, sondern in die Mikrotask-Warteschlange.
  • Diese Warteschlange hat eine höhere Priorität als die Rückrufwarteschlange.
  • Die Ereignisschleife überprüft zuerst diese Warteschlange, führt zuerst alle Aufgaben aus und geht dann zur Ausführung in die Rückrufwarteschlange.
  • Rückrufe auf Versprechen werden Mikrotasks genannt, daher auch die Bezeichnung Mikrotask-Warteschlange. Es gibt auch andere Mikrotasks, die hier jedoch derzeit nicht relevant sind. Die Ereignisschleife entscheidet, wann jeder Rückruf ausgeführt wird. Es verleiht Mikroaufgaben eine höhere Priorität als der Rückrufwarteschlange
  • Mikrotasks können inline vor allen anderen regulären Rückrufwarteschlangen unterbrochen werden.
  • Promise.resolve(): Erstellt ein Versprechen, das sofort aufgelöst wird, und sein Erfolgswert wird darin als Argument übergeben. Der Rückruf then() wird mit dem aufgelösten Wert als Argument aufgerufen.
console.log("Direct simple console BEGIN");
setTimeout(() => console.log("Text from Timer"),0);
Promise.resolve("Text from Promise").then(res => console.log(res));
console.log("Direct simple console END");

Order of Output:
Direct simple console BEGIN
Direct simple console END
Text from Promise
undefined
Text from Timer
Nach dem Login kopieren
  • Eine Mikrotask-Warteschlange kann sogar die Rückrufwarteschlange überlasten, selbst wenn sie viele Mikrotasks oder zeitaufwändige Mikrotasks enthält.
console.log("Direct simple console BEGIN");
setTimeout(() => console.log("Text from Timer"),0);
Promise.resolve("Text from Promise1").then(res => console.log(res));
Promise.resolve("Text from Promise2").then(res => {
  for(let i=0; i<5000; i++)
  console.log(res);
});
console.log("Direct simple console END");
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonJavaScript-Engine. 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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage