Eine kurze Diskussion über Makrotasks und Mikrotasks in js

Eine kurze Diskussion über Makrotasks und Mikrotasks in js

Hier ist eine Frage zu Makroaufgaben und Mikroaufgaben:

setzeTimeout(Funktion(){
  konsole.log('1')
});
 
neues Versprechen(Funktion(Auflösung){
  konsole.log('2');
     lösen();
}).dann(Funktion(){
 konsole.log('3')
});
 
konsole.log('4')

Wie ist die Ausführungsreihenfolge des obigen Codes?

Einige Freunde antworten möglicherweise: 2, 4, 1, 3

Ich schätze, die Überlegung ist: Weiß ich nicht, dass js zeilenweise ausgeführt wird? setTimeout ist asynchron, also wird es am Ende eingefügt. Weiter unten wird console.log(2) ausgeführt. .then() ist asynchron, also wird es am Ende eingefügt. Dann console.log(4); Dann gehe zur asynchronen Warteschlange, zuerst console.log(1); dann console.log(3) .

Ich war etwas in Panik und habe es in den Browser eingefügt, um es mir anzusehen:

Unglaublich

Verwirrt, ich kann den Betriebsmechanismus von JavaScript nur sorgfältig studieren!

1. Über JavaScript

JavaScript ist eine Single-Thread-Sprache, was bedeutet, dass jeweils nur eine Aufgabe ausgeführt werden kann. Wenn mehrere Aufgaben ausgeführt werden müssen, müssen sie in die Warteschlange gestellt und entsprechend der Warteschlange ausgeführt werden (die vorherige Aufgabe wird abgeschlossen, bevor die nächste Aufgabe ausgeführt wird).

2. JavaScript-Ereignisschleife

Da JS ein Single-Thread ist, ist es wie eine Cafeteria mit nur einem Fenster. Die Schüler müssen sich einzeln anstellen, um ihr Essen zu bekommen. Ebenso müssen JS-Aufgaben einzeln nacheinander ausgeführt werden. Dieser Modus ist einfach auszuführen, aber mit zunehmenden zukünftigen Anforderungen, Transaktionen und Anfragen wird die Ausführungseffizienz dieses Single-Thread-Modus zwangsläufig geringer. Solange die Ausführung einer Aufgabe lange dauert, können die nachfolgenden Aufgaben während dieser Zeit nicht ausgeführt werden.

Es kommt häufig vor, dass hochauflösende Bilder in Nachrichten sehr langsam geladen werden. Sollte unsere Webseite hängen bleiben, bis die Bilder vollständig angezeigt werden? Um dieses Problem zu lösen, unterteilt die JavaScript-Sprache die Aufgabenausführungsmodi in synchron und asynchron:

  • Synchronmodus: Dies ist der oben erwähnte Ausführungsmodus. Die letzte Aufgabe wartet, bis die vorherige Aufgabe beendet ist, bevor sie ausgeführt wird. Die Ausführungsreihenfolge des Programms ist konsistent und mit der Reihenfolge synchronisiert, in der die Aufgaben angeordnet sind.
  • Asynchroner Modus: Jede Aufgabe hat eine oder mehrere callback . Nachdem die vorherige Aufgabe abgeschlossen ist, wird die Rückruffunktion anstelle der nächsten Aufgabe ausgeführt. Die nächste Aufgabe wird ausgeführt, ohne auf die Fertigstellung der vorherigen Aufgabe zu warten. Daher stimmt die Ausführungsreihenfolge des Programms nicht mit der Reihenfolge der Aufgabenanordnung überein und ist asynchron.

Wenn wir den Inhalt der Karte in Worte fassen:

  • Synchrone und asynchrone Tasks gelangen jeweils an unterschiedliche Ausführungsorte. Synchrone Tasks gelangen in den Hauptthread, während asynchrone Tasks in Event Table und Registerfunktionen gelangen.
  • Wenn die angegebene Sache abgeschlossen ist, verschiebt Event Table diese Funktion in Event Queue .
  • Wenn die Aufgabe im Hauptthread abgeschlossen und leer ist, wird sie zur Event Queue weitergeleitet, um die entsprechende Funktion zu lesen und zur Ausführung in den Hauptthread einzugeben.
  • Der obige Vorgang wird kontinuierlich wiederholt und wird oft als Event Loop bezeichnet.

Mit Codeausdruck:

lass Daten = [];
$.ajax({
    url:blog.csdn.net,
    Daten:Daten,
    Erfolg:() => {
        console.log('Erfolgreich gesendet!');
    }
})
console.log('Codeausführung beendet');


Das Obige ist ein einfacher Ajax-Anforderungscode:

  • ajax greift auf Event Table zu und registriert den success der Rückruffunktion.
  • Führen Sie console.log aus („Codeausführung beendet“).
  • Das Ajax-Ereignis ist abgeschlossen und die Rückruffunktion wird success in Event Queue eingetragen.
  • Der Hauptthread liest den success der Rückruffunktion aus Event Queue und führt sie aus.

Ich glaube, dass Sie durch den obigen Text und Code ein vorläufiges Verständnis der Ausführungsreihenfolge von js haben. Dies ist jedoch auch der Grund, warum einige Freunde mit 2, 4, 1, 3 geantwortet haben.

Tatsächlich gibt es jedoch immer noch Tricks in der asynchronen Warteschlange. In unserer Interviewfrage befinden sich sowohl setTimeout als auch promise .then() in der asynchronen Warteschlange! Lassen Sie uns als Nächstes über diese Techniken (Makrotasks und Mikrotasks) sprechen.

3. Makroaufgaben und Mikroaufgaben

Jeder versteht darunter etwas anderes, da Makrotasks und Mikrotasks kein Standard sind, die Reihenfolge der Ausführung jedoch in js einheitlich ist.

Makroaufgaben:

# Browser Knoten
<script> Gesamtcode
setTimeout
Intervall festlegen
Sofort festlegen X
AnfrageAnimationFrame X
Ajax
DOM-Ereignisse

Mikroaufgaben:

# Browser Knoten
Prozess.nextTick X
MutationObserver X
Versprich es.dann fange es endlich

Zu den Makroaufgaben gehören : <script> Gesamtcode, setTimeout , setInterval , setImmediate , Ajax , DOM-Ereignisse
Mikrotasks : process.nextTick , MutationObserver , Promise.then catch finally

process.nextTick variiert zu stark, verschiedene Knoten werden nicht einheitlich ausgeführt und es gibt keinen Standard
Mikrotasks werden früher ausgeführt als Makrotasks

Tipp: Manche Leute packen den gesamten <script>-Code gerne in eine Makroaufgabe, aber ich persönlich mag das nicht. In meinem Fall ist es nur der Hauptausführungsthread. Ich persönlich klassifiziere sowohl Makroaufgaben als auch Mikroaufgaben als asynchrone Aufgaben!

Schauen wir uns die Interviewfrage noch einmal an:

//Callback ist eine asynchrone Aufgabe setTimeout(function(){//Makroaufgabe console.log('1')
});
 
neues Versprechen(Funktion(Auflösung){
  console.log('2');//Hauptthread synchronisieren resolve();
}).dann(Funktion(){//Mikrotask-Konsole.log('3')
});
 
console.log('4') //Hauptthread synchronisieren

2: Der erste in der Synchronisation, also der erste

4: Der zweite in der Synchronisation, also der zweite

3: Mikrotasks in asynchronen

1: Makroaufgabe in asynchron, also die zweite

Daher: Die Ergebnisse sind 2, 4, 3, 1!

Lassen Sie uns darüber hinaus näher darauf eingehen:

setTimeout(() => {//Makro-Task-Warteschlange 1
  console.log('1'); //Makro-Aufgabe Team 1 Aufgabe 1

  setTimeout(() => {//Makroaufgabenwarteschlange 3 (Makroaufgabe in Makroaufgabenwarteschlange 1)
    konsole.log('2')
  }, 0)

  neues Versprechen(lösen => {
    lösen()
    console.log('3') //Makro-Task-Warteschlange 1 Task 2
  }).then(() => {//Mikrotask in Makrotask-Warteschlange 1 console.log('4')
  })

}, 0)
 
setTimeout(() => {//Makro-Task-Warteschlange 2
  konsole.log('5')
}, 0)

console.log('6') //Hauptthread synchronisieren

Führen Sie den gesamten Code aus (Makrotask). console.log('6') >> Makrotask-Warteschlange 1 und Makrotask-Warteschlange 2 sind asynchron (werden nacheinander ausgeführt).

Makrotask-Warteschlange 1: =>

konsole.log('1')

konsole.log('3')

console.log('4') //Mikrotask in Makrotask

Der Rest wird nicht zuerst ausgeführt, da es sich um eine Makroaufgabe in einer Makroaufgabe (console.log(2)) handelt und später in die Aufgabenwarteschlange geworfen wird.

Makroaufgabenwarteschlange 2: =>

konsole.log('5')

Makrotask 3 in Makrotask-Warteschlange 1: =>

konsole.log('2')

Was gibt der obige Code aus?

4. Erweitern Sie Makrotasks und Mikrotasks

Die obige Frage ist kompliziert. Vielleicht möchten Sie darüber nachdenken. Wie sollten wir sie in dieser komplizierten Situation Schritt für Schritt ausführen?

  • 6: Der erste synchronisierte Haupt-Thread, also der erste

Da im Skriptcode keine Mikrotask vorhanden ist, wird die Makrotask direkt ausgeführt =>

Makrotask-Warteschlange:

Makrotask-Warteschlange 1

  • Aufgabe 1: console.log(1)
  • Aufgabe 2: console.log(3)
  • Mikrotask in Makrotask-Warteschlange 1: console.log(4)
  • Makroaufgabenwarteschlange 3: Da es sich um eine Makroaufgabe in der Makroaufgabenwarteschlange 1 handelt, wird sie am Ende in die Aufgabenwarteschlange geworfen. Wir prüfen zunächst, ob sich Makroaufgaben auf derselben Ebene wie die Makroaufgabenwarteschlange 1 befinden. Wenn dies der Fall ist, führen wir zuerst die Makroaufgaben auf derselben Ebene aus. Wenn nicht, können wir die Makroaufgabenwarteschlange 3 ausführen! So endlich!

Makrotask-Warteschlange 2

console.log(5)

Was ist also die Ausgabe? Es ist 6, 1, 3, 4, 5, 2!

Nach der Überprüfung ist das Ergebnis korrekt!

Dies ist das Ende dieses Artikels über Makroaufgaben und Mikroaufgaben in js. Weitere relevante Makroaufgaben und Mikroaufgaben in js finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den verwandten Artikeln weiter unten. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Details zu Makrotasks und Mikrotasks in JavaScript
  • JavaScript-Makrotasks und Mikrotasks
  • Eine kurze Diskussion über die Ausführungsreihenfolge von JavaScript-Makrotasks und Mikrotasks
  • Eine kurze Diskussion über die Prinzipien von JavaScript-Ereignisschleifen-Mikrotasks und Makrotask-Warteschlangen
  • Analyse der JavaScript-Ereignisschleife sowie der Prinzipien von Makro- und Mikro-Tasks
  • JS-Ereignisschleifenmechanismus Ereignisschleifen-Makrotask-Mikrotask-Prinzipanalyse
  • Erläuterung von JavaScript-Mikrotasks und Makrotasks

<<:  Einige Vorschläge zur Verbesserung der Nginx-Leistung

>>:  Eine Zusammenfassung der Fuzzy-Abfrage von MySQL wie

Artikel empfehlen

Zabbix-Überwachungslösung – die neueste offizielle Version 4.4 [empfohlen]

Zabbix 12.10.2019 Chenxin siehe https://www.zabbi...

Implementierung der kollaborativen Nutzung von React-Komponenten

Inhaltsverzeichnis Verschachtelung Kommunikation ...

So ändern Sie das Kennwort von mysql5.7.20 unter Linux CentOS 7.4

Nach dem Upgrade von MySQL auf Version 5.7 wurde ...

Vue3 kapselt die Lupeneffektkomponente der Jingdong-Produktdetailseite

In diesem Artikel wird der spezifische Code der V...

Vue+Flask realisiert Videosynthesefunktion (Drag & Drop-Upload)

Inhaltsverzeichnis Wir haben in einem früheren Ar...

Reines HTML+CSS, um einen Element-Ladeeffekt zu erzielen

Dies ist der Effekt der Element-UI-Ladekomponente...

Attribute und Verwendung von INS- und DEL-Tags

ins und del wurden in HTML 4.0 eingeführt, um Auto...

So stellen Sie per SSH eine Verbindung zum Docker-Server her

Als ich zum ersten Mal mit Docker in Berührung ka...

Eine kurze Diskussion über die Platzierung von Skripten in HTML

Früher dachte ich, dass Skripte überall in HTML p...

Grafisches Tutorial zur Installation von MySQL 5.6.35 unter Windows 10 64-Bit

1. Laden Sie MySQL Community Server 5.6.35 herunt...

Grafisches Tutorial zur Installation und Konfiguration der MySQL-Version 5.7.15

Dieser Artikel enthält ein ausführliches Tutorial...

js, um die Produktionsmethode des Karussells zu realisieren

In diesem Artikel wird der spezifische Code für j...

Zusammenfassung der sieben MySQL JOIN-Typen

Bevor wir beginnen, erstellen wir zwei Tabellen, ...