Dieser Artikel teilt Ihnen hauptsächlich eine Methode zur kurzen Analyse des JS-Ausführungsmechanismus mit. Er hat einen guten Referenzwert und ich hoffe, dass er für alle hilfreich sein wird. Kommen Sie vorbei und werfen Sie einen Blick mit dem Herausgeber
Bitte beachten Sie zunächst 2 Punkte:
(2) Die Ereignisschleife von JS ist der Ausführungsmechanismus von JS. Ein tiefes Verständnis der Ausführung von JS entspricht einem tiefen Verständnis der Ereignisschleife in JS
Die Entstehung der Technologie hängt eng mit Anwendungsszenarien in der realen Welt zusammen.
In ähnlicher Weise werden wir diese drei Fragen anhand realer Szenarien beantworten
(1) Warum ist JS Single-Threaded?
JS wurde ursprünglich für die Verwendung in Browsern entwickelt. Stellen Sie sich also vor, JS im Browser wäre multithreaded.
1 2 3 4 5 |
Szenenbeschreibung:
Jetzt gibt es also 2 Prozesse ,Prozess1 Prozess2 ,Da es sich um ein Mehrprozess-JS, handelt, arbeiten sie gleichzeitig auf demselben Dom, Gleichzeitig
Prozess1 löschte den Dom, und Prozess2 Das dom bearbeitet, 2 widersprüchliche Befehle gleichzeitig ausgegeben, Wie soll der Browser es ausführen? ? |
Wenn man es so betrachtet, sollte es leicht zu verstehen sein, warum JS für Single-Threading konzipiert ist.
(2) Warum braucht JS asynchron?
1 2 3 4 |
Szenenbeschreibung:
Wenn es in JS kein asynchrones gibt, kann nur von oben nach unten ausgeführt werden , Wenn die Analysezeit der vorherigen Zeile sehr lang ist , dann wird der folgende Code blockiert. Für Benutzer,Blockieren bedeutet„hängen bleiben“,Dies führt zu einer schlechten Benutzererfahrung |
Es gibt also eine asynchrone Ausführung in JS.
(3) Wie erreicht Single-Threaded JS eine asynchrone Implementierung?
Da JS Single-Threaded ist, kann es nur in ausgeführt werden Ein Thread Wie implementiert man die asynchrone Ausführung?
ist durch die Ereignisschleife. Wenn Sie den Ereignisschleifenmechanismus verstehen, werden Sie den Ausführungsmechanismus von JS verstehen
Beispiel 1, beobachten Sie die Ausführungssequenz
console.log(1) setTimeout(function(){ console.log(2) },0) console.log(3)
Das laufende Ergebnis ist: 1 3 2
In Mit anderen Worten, die Funktion in setTimeout wird nicht sofort ausgeführt, sondern um einen bestimmten Zeitraum verzögert und ausgeführt, nachdem bestimmte Bedingungen erfüllt sind. Diese Art von Code wird als asynchroner Code bezeichnet.
Hier kennen wir also zunächst eine Klassifizierungsmethode in JS, die darin besteht, Aufgaben in synchrone Aufgaben und asynchrone Aufgaben zu unterteilen
Bildbeschreibung
Gemäß dieser Klassifizierungsmethode: Der Ausführungsmechanismus von JS ist
Bestimmen Sie zunächst, ob JS synchron oder asynchron ist. Wenn es synchron ist, wird es in den Hauptprozess eingegeben, wenn es asynchron ist, wird es in die Ereignistabelle eingegeben
Die asynchrone Aufgabe registriert die Funktion in der Ereignistabelle. Wenn die Triggerbedingung erfüllt ist, wird sie in die Ereigniswarteschlange verschoben.
Die Die synchrone Aufgabe gelangt in den Hauptthread und wird ausgeführt, bis der Hauptthread inaktiv ist. Überprüfen Sie, ob ausführbare asynchrone Aufgaben vorhanden sind. Schieben Sie sie in den Hauptprozess
Die oben genannten drei Schritte werden in einer Schleife ausgeführt. Dies ist die Ereignisschleife
Können Sie für das obige Beispiel die Ausführungsreihenfolge beschreiben?
1 2 3 4 5 | Konsole.Protokoll(1) ist eine Synchronisierungsaufgabe , wird im Hauptthread platziertsetTimeout() ist eine asynchrone Aufgabe , wird in Ereignis <🎜 eingefügt > Tabelle, 0 Sekunden später wird in die Ereignis-Warteschlange verschoben Konsole.Protokoll(3 ist eine Synchronisierungsaufgabe , wird im Hauptthread platziert, wenn1, 3 ist in Nachdem die Steuerleiste gedruckt wurde , geht der Hauptthread zur Ereignis-Warteschlange(Ereigniswarteschlange) um zu sehen, ob es welche gibt Die ausgeführte Funktion , führt die Funktion | in
1 2 3 4 5 6 7 | setTimeout ist eine asynchrone Aufgabe , wird in Ereignis < platziert 🎜 >Tabelle neu Versprechen ist synchron Aufgabe, werden im Hauptprozess , platziert und führen direkt den Druck aus Konsole.Protokoll('For-Schleife jetzt ausführen') .dann< Die Funktionen in 🎜> sind asynchrone Aufgabe und wird in der Ereignis-Tabelle <🎜 platziert > Konsole.Protokoll('Codeausführung beendet') ist ein Synchronisationscode , wird im Hauptprozess platziert und wird direkt ausgeführt |
Das Ergebnis ist also [for-Schleife sofort ausführen – die Codeausführung endet – der Timer startet – die then-Funktion wird ausgeführt]
Nachdem ich es selbst ausgeführt habe, ist das Ergebnis nicht so, aber [sofort ausführen] Die for-Schleife – die Codeausführung endet – die then-Funktion wird ausgeführt – der Timer startet]
Ist es also die Reihenfolge der Ausführung asynchroner Aufgaben, nicht die Reihenfolge von vorher und nachher, sondern Andere Vorschriften? Tatsächlich ist die Synchronisierungsteilungsmethode laut asynchroner Methode nicht genau.
Die genaue Divisionsmethode lautet:
Makroaufgabe (Makroaufgabe): einschließlich des gesamten Codeskripts setTimeout, setInterval
Mikroaufgabe (Mikrotask): Promise, Process.nextTick
Gemäß dieser Klassifizierung: Der Ausführungsmechanismus von JS ist
Führen Sie eine Makroaufgabe aus. Wenn während des Vorgangs eine Mikroaufgabe auftritt, legen Sie sie in die [Ereigniswarteschlange] der Mikroaufgabe
Aktuelles Makro Nachdem die Aufgabenausführung abgeschlossen ist, wird die [Ereigniswarteschlange] der Mikrotask angezeigt und alle darin enthaltenen Mikrotasks werden nacheinander ausgeführt.
Wiederholen Sie die beiden oben genannten Schritte in Kombination mit dem Ereignis Schleife (1) Ereignisschleife (2) Dies ist ein genauerer JS-Ausführungsmechanismus.
Versuchen Sie, Beispiel 2 anhand des Ausführungsmechanismus zu analysieren, den Sie gerade gelernt haben:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Führen Sie zuerst die Makroaufgabe unter Skript aus, und wenn auf setTimeout trifft, legen Sie es in die [Warteschlange] des Makros Aufgabe
Begegnungen neu Versprechendirekt ausführen , drucken "Führen Sie die for-Schleife sofort aus"
Wenn Sie auf die then-Methode stoßen, ist eine Mikroaufgabe, Stellen Sie es in die [Warteschlange] der Mikroaufgabe
Drucken „Codeausführung endet“
Die Ausführung dieser Runde von Makroaufgaben ist abgeschlossen,Sehen Sie sich die Mikroaufgaben dieser Runde an,und stellen Sie fest, dass es dann eine Funktion gibt Methode, Drucken„Dann wird die Funktion ausgeführt“
Das ist es,Das Event Loop dieser Runde Alles abgeschlossen.
下一轮的循环里,先执行一个宏任务,发现宏任务的【队列】里有一个 setTimeout里的函数,执行打印"定时器开始啦" |
所以最后的执行顺序是【马上执行for循环啦 — 代码执行结束 — 执行then函数啦 — 定时器开始啦】
这段setTimeout代码什么意思? 我们一般说: 3秒后,会执行setTimeout里的那个函数
setTimeout(function(){ console.log('执行了') },3000)
但是这种说并不严谨,准确的解释是: 3秒后,setTimeout里的函数被会推入event queue,而event queue(事件队列)里的任务,只有在主线程空闲时才会执行。
所以只有满足 (1)3秒后 (2)主线程空闲,同时满足时,才会3秒后执行该函数
如果主线程执行内容很多,执行时间超过3秒,比如执行了10秒,那么这个函数只能10秒后执行了
Das obige ist der detaillierte Inhalt vonEine kurze Analyse des JS-Ausführungsmechanismus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!