I have the code below and I expect to first have hi in my console then the error and at the end why, but the result is: hi, then why and the last one is error, so I’m wondering, why is this happening?
code:
const test = new Promise((resolve, reject) => {
console.log("hi");
throw new Error("error");
})
test.finally(() => {
console.log("why")
})
>Solution :
I expect to first have
hiin my console then the error and at the endwhy
That’s what you’d get if you were handling the rejection of the promise, like this:
const test = new Promise((resolve, reject) => {
console.log("hi");
throw new Error("error");
});
test
.catch((error) => console.error(error))
.finally(() => {
console.log("why")
});
…but your code isn’t handling rejection, so the rejection isn’t reported until the environment’s unhandled rejection code kicks in, which isn’t until after all the code explicitly handling the promise has been executed.
As you’ve said in a comment, new Promise and the execution of the function you pass it are all synchronous, but the error thrown in that function isn’t unhandled, it’s handled by the Promise constructor and converted to a promise rejection (which, later, is unhandled).
So the sequence is:
- Create a promise
- Output
hi - Reject the promise with the error
- Attach a
finallyhandler to it - Run any appropriate handlers attached to the promise (since it’s settled), in this case your
finallyhandler- Output
why - Reject the promise created by
finally
- Output
- Determine that the rejection is unhandled and report it