JS Promises: Fulfill vs Resolve

前端 未结 4 902
我寻月下人不归
我寻月下人不归 2020-12-31 08:07

I understand Promises to exist in one of three states: A Promise can either be pending (unresolved), fulfilled (resolved successfully) or <

4条回答
  •  离开以前
    2020-12-31 08:43

    Indeed, the resolve callback does not imply that the promise will be fulfilled.

    The terms fulfilled, rejected, pending, settled, resolved and locked-in are defined in the EcmaScript2015 specs, 25.4 Promise Objects:

    Any Promise object is in one of three mutually exclusive states: fulfilled, rejected, and pending:

    • A promise p is fulfilled if p.then(f, r) will immediately enqueue a Job to call the function f.

    • A promise p is rejected if p.then(f, r) will immediately enqueue a Job to call the function r.

    • A promise is pending if it is neither fulfilled nor rejected.

    A promise is said to be settled if it is not pending, i.e. if it is either fulfilled or rejected.

    A promise is resolved if it is settled or if it has been “locked in” to match the state of another promise. Attempting to resolve or reject a resolved promise has no effect. A promise is unresolved if it is not resolved. An unresolved promise is always in the pending state. A resolved promise may be pending, fulfilled or rejected.

    A short overview, where I will use the term "autonomous" as the opposite of "locked in". They are the two possible values for a promise's dependency situation:

    +---------------------+------------+-----------+-----------+----------+
    | action              | dependency | state     | resolved? | settled? |
    +---------------------+------------+-----------+-----------+----------+
    | new Promise()       | autonomous | pending   |    no     |    no    |
    | - resolve(thenable) | locked-in  | pending*  |    yes    |    no    |
    | - resolve(other)    | autonomous | fulfilled |    yes    |    yes   |
    | - reject(any)       | autonomous | rejected  |    yes    |    yes   |
    +---------------------+------------+-----------+-----------+----------+
    

    * The thenable is now in control over the future state of our promise object.

    The above quote mentions that a promise is locked-in to match the state "of another promise", but more precisely that "other promise" could also be a non-promise "thenable" as can be seen in the steps 11 and 12 of the process description in 25.4.1.3.2

    1. If IsCallable(thenAction) is false, then
            a. Return FulfillPromise(promise, resolution).
    2. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «‍promise, resolution, thenAction»)

    A demo of resolve being called with a thenable, which in turn triggers a rejection:

    const thenable = { // Could be a promise object, but does not have to be
        then(success, fail) {
            setTimeout(() => fail("gotcha!"), 1000);
        }
    }
    
    const p = new Promise((resolve, reject) => {
        console.log("1. The promise is created as pending");
        setTimeout(() => {
            resolve(thenable);
            console.log("2. It's resolved with a thenable; it's not yet settled");
        }, 1000);
    });
    
    p.catch(err => 
       console.log(`3. It's settled as rejected with error message "${err}"`)
    );

提交回复
热议问题