Reputation: 69
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?
Upvotes: 4
Views: 77
Reputation: 530
This is because you're chaining .chatch()
to the result of .then()
function. 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"));
Upvotes: 2
Reputation: 447
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"));
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"));
Here's another example that shows that it doesn't matter if it's the catch
or then
, the next then
/catch
will be added to the microqueue only after the previous then
/catch
executes.
Promise.resolve().then().then().then(()=>console.log("Resolved1 Promise"));
Promise.reject().then().catch(()=>console.log("Rejected2 Promise"));
Promise.resolve().then(()=>console.log("Resolved3 Promise"));
Upvotes: 0