So I been reading a tutorial about Javascript promises these days.
here is an example from it used to explain the macrotask queue(i.e. the event loop) and the microtask queue.
let promise = Promise.reject(new Error("Promise Failed!"));
promise.catch(err => alert('caught'));
// no error, all quiet
window.addEventListener('unhandledrejection', event => alert(event.reason));
It says that because promise.catch
catches the error so the last line, the event handler never gets to run. I can understand this. But then he tweaked this example a little bit.
let promise = Promise.reject(new Error("Promise Failed!"));
setTimeout(() => promise.catch(err => alert('caught')));
// Error: Promise Failed!
window.addEventListener('unhandledrejection', event => alert(event.reason));
This time he says the event handler is gonna run first and catch the error and after this the promise.catch
catches the error eventually.
What I do not understand about the second example is, why did the event handler run before the promise.catch
?
My understanding is,
- Line one, we first encounter a promise, and we put it on the microtask queue.
- Line two, we have a
setTimeout
, we put it on the macrotask queue, - Line three, we have an event handler, and we put the handler on the macrotask queue waiting to be fired
Then, because microtask has higher priority than macrotask. We run the promise first. After it, we dequeue the first task on macrotask queue, which is the setTimeout
. So from my understanding, the error should be caught by the function inside setTimeout
.
Please correct me.