2015-08-17 4 views
8

Lassen Sie uns sagen, dass ich ein Versprechen wie dieses:Was passiert, wenn ein Versprechen abgeschlossen ist, bevor es aufgerufen wird?

var promise = new Promise(function(resolve, reject) { 
    // Do some async thing 
}); 
promise.then(function(response) { 
    // Then do some other stuff 
}); 

Was passiert, wenn die Asynchron Versprechen abgeschlossen geschieht, bevor ich .then nennen? Normalerweise hätte ich nur lange Aufgaben in der Promise-Funktion, aber was, wenn es wirklich schnell einmal abgeschlossen wird?

Antwort

13

Wie erwartet: dann wird Callback in diesem Fall sofort aufgerufen, wenn der Aufruf dann erfolgte, nachdem das Versprechen bereits gelöst wurde.

Es ist einfach zu testen:

var promise = new Promise(function(resolve, reject) { 
 
    resolve(123); 
 
}); 
 

 
setTimeout(function() { 
 
    promise.then(function(response) { 
 
     alert(response); 
 
    }); 
 
}, 1000)

+7

"sofort" ist in diesem Fall ein bisschen irreführend oder bestenfalls nicht beschreibend genug. Es wird bald aufgerufen, aber immer noch asynchron aufgerufen. Alle '.then() 'Handler werden immer asynchron mit den Versprechungen der Promise-Spezifikation aufgerufen. Eine Codezeile direkt nach 'promise.then (...)' wird also ausgeführt, BEVOR die '.then()' --Handlerfunktion aufgerufen wird, auch wenn das Versprechen bereits gelöst ist. – jfriend00

+0

Was jFriend sagt, aber mit der Maßgabe, dass jQuery verspricht, sind nicht Standard. Eine der wichtigsten Kritikpunkte an jQuery ist, dass eine 'then()', die an ein bereits festgelegtes Versprechen angekettet ist, ihren Erfolgs- oder Fehlerrückruf synchron im selben Ereignis-Thread auslöst. Wir verstehen, dass dieses Verhalten in jQuery v3 behoben wird. –

2

Der then Rückruf wird nie resolved ist das Versprechen aufgerufen, das ist, was ich glaube, Sie durch vollständige bedeuten. Wenn eine Zusage jedoch aufgelöst wird, bevor sie von einer Funktion zurückgegeben wird, werden alle weiteren Erfolgsrückrufe, die nach diesem Zeitpunkt verkettet sind, weiterhin ausgeführt. Zum Beispiel

function getMeAResolvedPromise() { 
    var prom = new Promise(); 
    prom.resolve('some val'); 
    return prom; 
} 

... 

getMeAResolvedPromise.then(function(result) { 
    // this will still be executed 
}); 
3

Ein Versprechen hat Zustand, was bedeutet, dass auch nach dem Versprechen erfüllt wird, Sie Rückrufe mit .then daran anschließen kann, und sie werden mit dem gleichen Ergebnis aufgerufen werden, als ob das Versprechen erfüllt wurde nachdem sie verbunden waren.

Erfüllt ist der Endzustand eines erfolgreichen Versprechens. Dies bedeutet, dass Sie in Zukunft weitere Handler an das erfüllte Versprechen anfügen können, indem Sie das Versprechen als Cache für die ursprüngliche Antwort verwenden.

.then() on MDN

dann()

Ruft eine der angebotenen Funktionen, sobald diese Versprechen entweder erfüllt oder abgelehnt ist. Es wird eine neue Zusage zurückgegeben, deren Status abhängig von dieser Zusage und den bereitgestellten Callback-Funktionen ist.

Der entsprechende Rückruf wird immer aufgerufen, wenn diese Methode zurückgibt, selbst wenn diese Zusage bereits erfüllt oder zurückgewiesen wurde. Sie können auch die then-Methode mehrere Male auf die gleiche Verheißung aufrufen, und die Callbacks werden in derselben Reihenfolge aufgerufen, wie sie registriert wurden.

4

Wie andere bereits hingewiesen haben, können Sie Rückrufe mit .then vor oder nach dem Versprechen gelöst wurde hinzufügen, und Sie können sogar mehr als ein Callback hinzufügen.

Diese Callbacks werden in der Reihenfolge aufgerufen, in der sie hinzugefügt wurden, aber immer asynchron, nach der aktuelle Turn der Ereignisschleife. Wenn also das Versprechen bereits gelöst wurde, wenn Sie eine .then hinzufügen, wird Ihr Handler sofort aufgerufen, aber im "ascynchronen Sinne".

Die Promises/A+ spec sagt:

[...] onFulfilled und onRejected asynchron ausführen, nach der Ereignisschleife, in der then aufgerufen wird, und mit einem frischen Stapel.

Verwandte Themen