Roman Karagodin
Roman Karagodin

Reputation: 859

JS: what happens if to return a new Promise inside a callback of a then-statement

While messing with JavaScript Promises, I noticed a strange thing: if to return a new Promise inside a callback of a then-statement, such a then-statement seems to pass to the next "then" NOT this new Promise, but the result of the latter being resolved! An example:

new Promise(resolve => { resolve() })
.then(() => {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(1);
        }, 1000);
    })
})
.then(x => {
    console.log(typeof x, x);
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(2);
        }, 1000);
    })
})
.then(x => {
    console.log(typeof x, x);
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(3);
        }, 1000);
    })
})
.then(x => {
    console.log(typeof x, x);
})

What I get in the console after this, is:

number 1
number 2
number 3

, which is definitely NOT what I expected, as I know that a then-statement's callbacks should accept a return value of a previous then statement's callback – so I expected to see in the console objects (Promises) instead of numbers... Did I miss something?

Upvotes: 1

Views: 1352

Answers (3)

Yousaf
Yousaf

Reputation: 29282

When you return something from a callback function of .then() method, if that return value is a non-promise value, then it is implicitly wrapped in a promise and then the promise returned by that .then() method is fulfilled with that non-promise value.

On the other hand, if the return value of the callback function is itself a promise, then the promise returned by the .then() method gets resolved to the promise returned by the callback function. This means that the fate of the promise returned by the .then() method now depends on whatever happens to the promise returned by the callback function.

Example: Assume that the promise returned by the .then() method is promiseThen and the promise returned by the callback function is promiseCallback. Now, if the promiseCallback is fulfilled, then the promiseThen will also fulfill with the value with which promiseCallback fulfilled and this value is what will be passed to the next .then() method, if there is one. Similarly, if promiseCallback is rejected, then promiseThen will also get rejected.

Upvotes: 2

Anand Raj
Anand Raj

Reputation: 443

In your code, there is a promise chain. Please refer https://javascript.info/promise-chaining

In a promise chain, execution of promise then callbacks takes place one after another.

i.e Second promise callback is not executed until the first promise callback execution is completed(first promise enters resolved state). Similarly it goes down till the last promise callback in the execution chain.

If any one of the promise callbacks in a promise chain is failed (promise enters rejected state), then the promise callback execution stops there.

i.e. Second promise callback will not be executed if first promise callback fails

To answer your question

This article gives an in-depth view of Promise similar to your question https://codeburst.io/playing-with-javascript-promises-a-comprehensive-approach-25ab752c78c3

You returned a promise object inside the first then callback. So, the next then (second then) callback will not be executed until the promise returned by first then callback enters resolved state or completes execution

Upvotes: 2

Andreas
Andreas

Reputation: 21881

Promise.prototype.then()

The then() method returns a Promise. It takes up to two arguments: callback functions for the success and failure cases of the Promise.

...

Return value

Once a Promise is fulfilled or rejected, the respective handler function (onFulfilled or onRejected) will be called asynchronously (scheduled in the current thread loop). The behavior of the handler function follows a specific set of rules. If a handler function:

  • returns a value, the promise returned by then gets resolved with the returned value as its value.
  • doesn't return anything, the promise returned by then gets resolved with an undefined value.
  • throws an error, the promise returned by then gets rejected with the thrown error as its value.
  • returns an already fulfilled promise, the promise returned by then gets fulfilled with that promise's value as its value.
  • returns an already rejected promise, the promise returned by then gets rejected with that promise's value as its value.
  • returns another pending promise object, the resolution/rejection of the promise returned by then will be subsequent to the resolution/rejection of the promise returned by the handler. Also, the resolved value of the promise returned by then will be the same as the resolved value of the promise returned by the handler.

Source: MDN

The last (bold) bullet point is the answer to your question

Upvotes: 2

Related Questions