skip to Main Content

I am learning microtask queue and i have a simple question.

With the following code:

Promise.resolve().then(()=>console.log("Resolved1 Promise"));
Promise.reject().then(()=>console.log("Resolved2 Promise")).catch(()=>console.log('Rejected2 Promise'));
Promise.resolve().then(()=>console.log("Resolved3 Promise"));
Promise.resolve().then(()=>console.log("Resolved4 Promise"));
Promise.resolve().then(()=>console.log("Resolved5 Promise"));

I expected output to be in the sequence:

Resolved1 Promise
Rejected2 Promise
Resolved3 Promise
Resolved4 Promise
Resolved5 Promise

But as you can try above, rejected callback is triggered in the last. Can anyone explain it to me?

2

Answers


  1. This is because of JavaScript’s internal timings and is caused by 2nd the promise (the one that rejects) having both .then() and .catch() callbacks. This can be fixed by removing .then() from the promise:

    Promise.resolve().then(() => console.log("Resolved1 Promise"));
    Promise.reject().catch(() => console.log('Rejected2 Promise'));
    Promise.resolve().then(() => console.log("Resolved3 Promise"));
    Promise.resolve().then(() => console.log("Resolved4 Promise"));
    Promise.resolve().then(() => console.log("Resolved5 Promise"));

    Optionally, if you want to listen for both events, use a sigle .then() call to assign both listeners:

    Promise.resolve().then(() => console.log("Resolved1 Promise"));
    Promise.reject().then(
        () => console.log("Resolved2 Promise"),
        () => console.log('Rejected2 Promise')
    );
    Promise.resolve().then(() => console.log("Resolved3 Promise"));
    Promise.resolve().then(() => console.log("Resolved4 Promise"));
    Promise.resolve().then(() => console.log("Resolved5 Promise"));
    Login or Signup to reply.
  2. Code snippet:

    Promise.resolve().then(()=>console.log("Resolved1 Promise"));
    Promise.reject().then(()=>console.log("Resolved2 Promise")).catch(()=>console.log("Rejected2 Promise"));
    Promise.resolve().then(()=>console.log("Resolved3 Promise"));

    Output:

    Resolved1 Promise
    Resolved3 Promise
    Rejected2 Promise
    

    The output order is due to the following sequence of microtask queue operations:

    Step Microtask Added to Queue Callback Executed Output
    1 Promise.resolve().then() console.log("Resolved1 Promise") Resolved1 Promise
    2 Promise.reject().then().catch() undefined (adds .catch() to the queue for step 4) no output yet
    3 Promise.resolve().then() console.log("Resolved3 Promise") Resolved3 Promise
    4 Promise.reject().then().catch() console.log("Rejected2 Promise") Rejected2 Promise

    When the rejected promise skips .then(), its .catch() runs in the next microtask after the first .then() but before subsequent .then() callbacks:

    Promise.resolve().then(()=>console.log("Resolved1 Promise"));
    Promise.reject().catch(()=>console.log("Rejected2 Promise"));
    Promise.resolve().then(()=>console.log("Resolved3 Promise"));

    The .then() method accepts two optional arguments: onFulfilled (for resolved promises) and onRejected (for rejected promises). In this case, the second Promise.reject() can have an explicit onRejected in .then() that prevents the rejection from propagating to .catch(). For more details on onFulfilled and onRejected, see https://promisesaplus.com/#the-then-method.

    Promise.resolve().then(()=>console.log("Resolved1 Promise"));
    Promise.reject().then(undefined, ()=>console.log("Rejected2 Promise")).catch(()=>console.log("Rejected2 Promise"));
    Promise.resolve().then(()=>console.log("Resolved3 Promise"));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search