Home > Enterprise >  Why a resolved promise still in pending state?
Why a resolved promise still in pending state?

Time:12-17

Example:

let a = Promise.resolve("123")
        .then(val => {
                console.log(a);
                return 100;
        })
        .then(val => {
                console.log(val);
                console.log(a);
        })
        .finally(() => {
                console.log(a);
        });

Output:

Promise { <pending> }
100
Promise { <pending> }
Promise { <pending> }

Why a resolved promise still in pending state?

CodePudding user response:

So, a contains the result of executing all of this:

let a = Promise.resolve(...).then(...).then(...).finally(...);

Each step of that phase creates a new promise and a contains the last one in the chain (the last promise is the one that .finally() returns). Each time you log a, you're logging the final promise and is has not yet been resolved until the chain is done.

Keep in mind that all these .then() and .finally() methods execute immediately and each returns a new promise. When they execute, they register the callbacks passed to them in a way that those callbacks can be called later when the promise they are associated with resolves or rejects. Even though the first promise is immediately resolved, it still doesn't execute it's .then() handlers until after this whole chain of .then().then().finally() executes and all the promise in that chain are created and all the handlers specified in that chain are registered. So, a contains the fourth promise that .finally() returns, not the promise that Promise.resolve() creates and that fourth promise is not resolved until after all the handlers in your chain have finished executing. Since you're doing the logging from all those handlers, that's why that last promise in the chain still shows as pending everywhere you're logging it.

If you do things differently like this:

let d = Promise.resolve("123");

d.then(val => {
    console.log(d);
    return 100;
}).then(val => {
    console.log(val);
    console.log(d);
}).finally(() => {
    console.log(d);
});

Then, you will see this:

Promise { '123' }
100
Promise { '123' }
Promise { '123' }

Because now d represents the first promise in the chain, not the end promise in the chain so it is indeed resolved when all the other handlers execute.

So, probably the operative part here that you were not aware of is that each .then(), .catch() or .finally() returns a new promise that is hooked to the chain in front of it. Your original console.log(a) was monitoring only the very last promise in the chain, not the first promise in the chain or not the current promise in the chain.

  • Related