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
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:Optionally, if you want to listen for both events, use a sigle
.then()
call to assign both listeners:Code snippet:
Output:
The output order is due to the following sequence of microtask queue operations:
console.log("Resolved1 Promise")
Resolved1 Promise
.catch()
to the queue for step 4)console.log("Resolved3 Promise")
Resolved3 Promise
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:The
.then()
method accepts two optional arguments:onFulfilled
(for resolved promises) andonRejected
(for rejected promises). In this case, the secondPromise.reject()
can have an explicitonRejected
in.then()
that prevents the rejection from propagating to.catch()
. For more details ononFulfilled
andonRejected
, see https://promisesaplus.com/#the-then-method.