Heim  >  Artikel  >  Web-Frontend  >  Probleme mit der Ausführungsreihenfolge von Promise und SetTimeout in JavaScript (Codebeispiel)

Probleme mit der Ausführungsreihenfolge von Promise und SetTimeout in JavaScript (Codebeispiel)

不言
不言nach vorne
2019-01-26 09:13:473277Durchsuche

In diesem Artikel geht es um die Ausführungsreihenfolge von Promise und SetTimeout in JavaScript (Codebeispiele). Ich hoffe, dass er für Sie hilfreich ist.

Promise ist ein von es6 eingeführter Sprachstandard und eine Lösung für die asynchrone Programmierung

Voraussetzung zum Lesen dieses Artikels ist das Verständnis des Mechanismus der Browser-Ereignisschleife sowie der grundlegenden Verwendung B. die Selbstausführungsfunktion, die Zustandsirreversibilitätsfunktion usw.

Wirft ein Problem aus

Sehen Sie sich den folgenden Code und das folgende Problem an

setTimeout(function(){console.log(1)},0);
new Promise(function(resolve){
    console.log(2)
    for( var i=0 ; i<10000 ; i++ ){
        i==9999 && resolve()
    }
    console.log(3)
}).then(function(){
    console.log(4)
});
console.log(5);
// 这的问题是,为什么答案是 2 3 5 4 1
// 而不是 2 3 5 1 4

Seit dem Versprechen .then und setTimeout sind beide asynchron. Dann sollte das Ereignis von Promise.then in der Ereignisschleifenwarteschlange hinter setTimeout eingeordnet werden. Warum wird Promise.then vor SetTimeout gedruckt?

Wichtige Konzepte

Das Konzept der Ereignisschleife

  • Javascript ist Single-Threaded und alle Synchronisierungsaufgaben werden im Hauptthread ausgeführt.

  • Nachdem alle Aufgaben im Hauptthread ausgeführt wurden, liest das System „sequentiell“ die Ereignisse in der Aufgabenwarteschlange. Die entsprechende asynchrone Aufgabe tritt in den Hauptthread ein und beginnt mit der Ausführung.

  • Es wird Unterschiede zwischen asynchronen Aufgaben geben, daher werden auch ihre Ausführungsprioritäten unterschiedlich sein. Sie werden grob in Mikroaufgaben (Mikroaufgaben wie Promise, MutaionObserver usw.) und Makroaufgaben (Makroaufgaben wie setTimeout, setInterval, I/O usw.) unterteilt.

  • Der Code im Promise-Executor wird synchron aufgerufen, der Rückruf basiert jedoch auf Mikrotasks.

  • Makroaufgaben haben eine höhere Priorität als Mikroaufgaben

  • Nachdem jede Makroaufgabe ausgeführt wurde, muss die aktuelle Mikroaufgabenwarteschlange gelöscht werden

  • Der Code des ersten Skript-Tags ist die erste Makroaufgabe

  • Der Hauptthread wiederholt die oben genannten Schritte so lange, bis alle Aufgaben ausgeführt sind.

Mein Verständnis

Lassen Sie uns den Ausführungsprozess des Codes durchgehen

Der gesamte Code ist im Skript-Tag geschrieben, also lesen Sie alles Code ist die erste Makroaufgabe, und wir beginnen mit der Ausführung der ersten Makroaufgabe.

Wir stoßen zuerst auf setTimeout, die zweite Makroaufgabe. Wir werfen sie in die Makrotask-Ereigniswarteschlange und stellen sie zuerst in die Warteschlange.

Als nächstes stoßen wir auf ein Versprechen. Der Code im Versprechen-Executor wird synchron aufgerufen, sodass wir 2 und 3 nacheinander ausdrucken.

Wenn Sie auf den Rückruf des Versprechens stoßen, handelt es sich um eine Mikrotask, und wir werfen ihn in die Mikrotask-Ereigniswarteschlange.

Als nächstes drucken wir 5 aus, führen dann die Mikroaufgabe aus und drucken 4 aus.

Unsere erste Makroaufgabe ist abgeschlossen, wir führen die nächste Makroaufgabe aus und drucken 1 aus. An diesem Punkt Alle Aufgaben werden erledigt.

Unser Endergebnis ist also 2 3 5 4 1.

Das obige ist der detaillierte Inhalt vonProbleme mit der Ausführungsreihenfolge von Promise und SetTimeout in JavaScript (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen