What happens if a promise completes before then is

2019-02-11 22:15发布

问题:

Let's say I have a Promise like this:

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

What happens if the async Promise completes before I call .then()? Normally, I'd only have long running tasks in the Promise function, but what if it completes really quickly one time?

回答1:

As expected: then callback will get called immediately in this case if then was called after promise has already resolved.

It's easy to test:

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

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



回答2:

As others have already pointed out, you can add callbacks with .then before or after the promise has been resolved, and you can even add more than one callback.

These callbacks will be called in the order they were added, but always asynchronously, after the current turn of the event loop. So if the promise has already been resolved when you add a .then, your handler will be called immediately, but in the "ascynchronous sense".

The Promises/A+ spec says:

[...] onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack.



回答3:

A promise has state, which means that even after the promise gets fulfilled, you can attach callbacks using .then to it, and they will be called, with the same result as if the promise was fulfilled after they were attached.

Fulfilled is the final state of a successful promise. This means that you can attach more handlers to the fulfilled promise in the future, using the promise as a cache for the original response.

.then() on MDN

then()

Calls one of the provided functions as soon as this promise is either fulfilled or rejected. A new promise is returned, whose state evolves depending on this promise and the provided callback functions.

The appropriate callback is always invoked after this method returns, even if this promise is already fulfilled or rejected. You can also call the then method multiple times on the same promise, and the callbacks will be invoked in the same order as they were registered.



回答4:

The then callback will never get called before the promise is resolved, which is what I think you mean by complete. However, if a promise is resolved before it is returned from a function, any additional success callbacks chained after that moment will still be executed. For example,

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

...

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