web-dev-qa-db-de.com

Warum werden Javascript ES6-Versprechen nach einer Lösung weiterhin ausgeführt?

Nach meinem Verständnis kann ein Versprechen aufgelöst () oder abgelehnt () werden. Ich war jedoch überrascht, dass der Code in dem Versprechen nach dem Aufrufen eines Auflösungs- oder Ablehnungsbefehls weiterhin ausgeführt wird.

Ich betrachtete resolide oder reject als eine asynchrone Version von exit oder return, die jede sofortige Funktionsausführung stoppen würde.

Kann jemand den Gedanken dahinter erklären, warum im folgenden Beispiel manchmal die Datei console.log nach einem Auflösungsaufruf angezeigt wird:

var call = function() {
    return new Promise(function(resolve, reject) {
        resolve();
        console.log("Doing more stuff, should not be visible after a resolve!");
    });
};

call().then(function() {
    console.log("resolved");
});

jsbin

73

JavaScript hat das Konzept von "run to completion" . Sofern kein Fehler ausgelöst wird, wird eine Funktion ausgeführt, bis eine return -Anweisung oder ihr Ende erreicht ist. Ein anderer Code außerhalb der Funktion kann dies nicht stören (es sei denn, es wird erneut ein Fehler ausgegeben).

Wenn Sie möchten, dass resolve() Ihre Initialisierungsfunktion verlässt, müssen Sie return voranstellen:

return new Promise(function(resolve, reject) {
    return resolve();
    console.log("Not doing more stuff after a return statement");
});
116
Felix Kling

Die Rückrufe, die aufgerufen werden, wenn Sie resolve ein Versprechen abgeben, müssen von der Spezifikation weiterhin asynchron aufgerufen werden. Dies soll ein konsistentes Verhalten sicherstellen, wenn Versprechungen für eine Mischung aus synchronen und asynchronen Aktionen verwendet werden.

Wenn Sie also resolve aufrufen, ist der Rückruf in der Warteschlange, und die Funktionsausführung wird sofort mit jedem Code fortgesetzt, der auf den Aufruf von resolve() folgt.

Erst wenn die JS-Ereignisschleife die Rücksteuerung erhält, kann der Rückruf aus der Warteschlange entfernt und tatsächlich aufgerufen werden.

18
Alnitak