Wie ist die Beziehung zwischen Ereignisschleife und Versprechen [duplicate]

Lesezeit: 5 Minuten

Wie ist die Beziehung zwischen Ereignisschleife und Versprechen duplicate
SeiteYe

Ich bin neugierig auf die Beziehung zwischen Event Loop und Promise.
Die Demo stellt die Frage. Ich habe die erwartet p1 fulfilled erscheinen in der Mitte, da sie eine Aufgabe in dieselbe Aufgabenwarteschlange einreihen und nacheinander ausgeführt werden.

var p1 = new Promise(function(resolve, reject){
    resolve(1)
})
setTimeout(function(){
  console.log("will be executed at the top of the next Event Loop")
},0)
p1.then(function(value){
  console.log("p1 fulfilled")
})
setTimeout(function(){
  console.log("will be executed at the bottom of the next Event Loop")
},0)

Das Konsolenergebnis ist:

p1 fulfilled
will be executed at the top of the next Event Loop
will be executed at the bottom of the next Event Loop

Der visualisierte Effekt zeigt die promise.thenDer Rückruf von wurde nicht in die Aufgabenwarteschlange der Ereignisschleife verschoben. Es ist richtig?

【HINWEIS: Die Frage ist nicht dasselbe wie Promise vs. setTimeout, da sie sich mehr auf die Beziehung zwischen Event Loop und Promise konzentriert】

  • Sie können sich eine zweite Aufgabenwarteschlange vorstellen, die am Ende des aktuellen verarbeitet wird Tick dh vor irgendetwas in der normalen Aufgabenwarteschlange.

    – Spinnen Schwein

    23. September 2017 um 3:39 Uhr

  • setTimeout hat auch eine minimale Verzögerung.

    – zzzzBov

    23. September 2017 um 3:52 Uhr

  • „Ich habe das erwartet p1 fulfilled in der Mitte erscheinen.” Warum erwarten Sie dieses Ergebnis?

    – Gast271314

    23. September 2017 um 4:06 Uhr

  • @torazaburo es ist kein Duplikat. Die Frage Promise vs setTimeout ist nur ein Beispiel, um die Beziehung zwischen Event Loop und Promise aufzuzeigen. Und ich bekomme genau die super Antwort, die ich will. Bitte nicht als Duplikat kennzeichnen

    – PageYe

    26. September 2017 um 3:12 Uhr

  • @PageYe Dann stimmen Sie für die Wiedereröffnung und lassen Sie die Leute entscheiden.

    Benutzer663031

    26. September 2017 um 3:54 Uhr

Wie ist die Beziehung zwischen Ereignisschleife und Versprechen duplicate
JiangangXion

Jede Ereignisschleife hat eine Mikrotask-Warteschlange und eine Makrotask-Warteschlange.

Eine Mikrotask ist eine Aufgabe, die ursprünglich eher in die Mikrotask-Warteschlange als in eine Aufgabenwarteschlange eingereiht werden soll. Beziehen auf https://www.w3.org/TR/html51/webappapis.html#microtask-queue.

Es gibt zwei Arten von Mikroaufgaben:

  • einsame Callback-Mikrotasks, wie z Promise
  • und zusammengesetzte Mikroaufgaben, wie z Object.observe, MutationObserver und process.nextTick in Node.js.

Und die Makrotask-Warteschlange enthält hauptsächlich setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O in Nodejs.

In einer Ereignisschleife werden diese beiden Aufgabenwarteschlangen in zwei Schritten ausgeführt:

  1. Überprüfen Sie zuerst, ob es in der alten Makrotask-Warteschlange einen Makrotask (nennen Sie ihn X) gibt;
  2. Wenn X existiert und ausgeführt wird, warten Sie, bis es mit dem nächsten Schritt fortfährt, bis es abgeschlossen ist; andernfalls gehe sofort zum nächsten Schritt;
  3. Zweitens alle Mikrotasks der Mikrotask-Warteschlange ausführen;
  4. und wenn die Mikrotasks ausgeführt werden, können wir immer noch einige weitere Mikrotaks in die Warteschlange einfügen, diese Aufgaben werden ebenfalls ausgeführt.

In deinem Beispiel:

  1. Initialisieren Sie zuerst Ihr Promise new Promise und resolve sind synchron;
  2. und dann synchron a hinzufügen setTimeout macroTask in die Makrotask-Warteschlange;
  3. dann fügen Sie die Mikrotask synchron hinzu promise.then(function(){}) In die Mikrotask-Warteschlange wird diese Aufgabe sofort ausgeführt, da die Promise-Initialisierung und -Auflösung synchron sind, wird diese Aufgabe vor jeder Makroaufgabe ausgeführt. also, console.log die p1 fulfilled;
  4. Fügen Sie dann die zweite Makroaufgabe hinzu setTimeout zur Makrotask-Warteschlange;
  5. Führen Sie nach dem Ende dieser Ereignisschleife die beiden Makrotasks aus.

für diesen Code:

setTimeout(function(){
  console.log("will be executed at the top of the next Event Loop")
},0)
var p1 = new Promise(function(resolve, reject){
    setTimeout(function(){resolve(1)},0)
});
setTimeout(function(){
    console.log("will be executed at the bottom of the next Event Loop")
},0)
for (var i = 0; i < 100; i++) {
    (function(j){
        p1.then(function(value){
           console.log("promise then - " + j)
        });
    })(i)
}

die Ausgabereihenfolge:

will be executed at the top of the next Event Loop
promise then - 0
promise then - 1
promise then - 2
...
promise then - 99
will be executed at the bottom of the next Event Loop
  1. Fügen Sie zuerst drei Makroaufgaben hinzu setTimeout Makrotask-Warteschlange und eine Mikrotask promise.then() zur Mikrotask-Warteschlange;
  2. einen Makrotask ausführen;
  3. Wenn die Bedingung wahr ist, werden alle Mikrotasks ausgeführt, aber sie ist falsch, also fahren Sie mit dem nächsten Schritt fort;
  4. führen Sie die zweite Makroaufgabe aus;
  5. Überprüfen Sie, ob das Versprechen aufgelöst wurde oder nicht, die Bedingung wahr ist, und führen Sie dann alle Mikrotasks aus.
  6. fahren Sie fort, andere Makrotasks auszuführen;

  • du sagst X Geprüft wird allerdings erst das setTimeout macroTask in Schritt 2 die X? warum nicht zuerst ausführen?

    – PageYe

    23. September 2017 um 15:33 Uhr

  • Da Ihr Versprechen initialisieren und auflösen synchron sind, überprüfen Sie also in Schritt eins, ob es eine Makroaufgabe (mit dem Namen X) in der alten Makroaufgabenwarteschlange gibt, es wird falsch zurückgegeben. Erst nach dem synchronen Code, der setTimeout Makrotask wird aufgerufen.

    – Jiangang Xiong

    24. September 2017 um 2:12 Uhr

  • Da w3.org nichts über die Makrotask-Warteschlange sagt, was ist der Unterschied zwischen der Makrotask-Warteschlange und der Aufgabenwarteschlange? Ist die Microtask Queue konzeptionell gesehen eine Art Task Queue oder sind sie komplett anders?

    – PageYe

    26. September 2017 um 3:36 Uhr


  • “solitäre Callback-Mikrotasks wie Promise” Wäre es richtig, hier genauer zu sein und stattdessen zu sagen: “solitäre Callback-Mikrotasks, die nur mit Promise.prototype.then() oder await erstellt werden können”

    – AnonGl

    4. Juli 2019 um 15:05 Uhr


Promises werden nicht abgerufen, es sei denn, der Stapel ist frei von Anwendungscode gemäß Dr. Axel Rauschmayer Hier.

… die Promises/A+-Spezifikation verlangt, dass immer letztere Ausführungsart verwendet wird. So heißt es im Folgenden Erfordernis (2.2.4) für die then()-Methode:

onFulfilled oder onRejected dürfen nicht aufgerufen werden, bis der Ausführungskontextstapel nur Plattformcode enthält.

Es ist wichtig zu beachten:

Das bedeutet, dass sich Ihr Code auf die Run-to-Completion-Semantik verlassen kann (wie in Teil 1 erläutert) und dass das Verketten von Promises andere Aufgaben nicht an Verarbeitungszeit verschwendet.

  • Ich verstehe nicht, wie dies die Frage beantwortet. Im Beispiel des OP ist die then Klausel war angerufen, während es anhängig war setTimeout Aufgaben, vorausgesetzt, diese gelten als “Anwendungscode” oder “Plattformcode”, dessen Definition ich nicht kenne – was bedeuten sie?

    Benutzer663031

    23. September 2017 um 5:00 Uhr

995790cookie-checkWie ist die Beziehung zwischen Ereignisschleife und Versprechen [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy