Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Questions about the order of execution of this code snippet

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,

  1. Line one, we first encounter a promise, and we put it on the microtask queue.
  2. Line two, we have a setTimeout, we put it on the macrotask queue,
  3. 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.

like image 728
Joji Avatar asked May 31 '19 22:05

Joji


People also ask

Which will execute first promise or setTimeout?

The reason the promise is executing before your timeout is that the promise isn't actually waiting for anything so it resolved right away. @frankies That has more to do with the way Promises are queued and resolved. The focus of my answer is the difference between setTimeout and Promise .

Which line of code will be executed first by the browser?

The server side code is executed first and the output generated by server side is sent back to client where client side code is executed. Show activity on this post. Yes, normally, the whole server processing finished before the page is delivered to the browser. At this moment, JavaScript execution starts.

What is the order of execution in JavaScript?

Order of execution in JavaScript is dependent on the following components working together to pass and order information. We can think through the order of execution using the (sometimes headache inducing) example of the asynchronous fetch request.


1 Answers

You are wrong about step 3). The handler will be added synchronously. Then the microtask queue gets run, and the promise rejects. As no .catch handler was added yet, an unhandled rejection gets thrown.

And I think you are mixing between when a callback gets added and when a callback gets executed. Consider this case:

  (new Promise).then(function callback() { });

The callback will be added synchronously, but it will never be called as the promise never resolves. In this case:

  Promise.resolve().then(function callback() { });

the callback again gets added synchronously, but the promise resolution happens in a microtask, so the callback will be executed a tick later.

like image 78
Jonas Wilms Avatar answered Sep 21 '22 21:09

Jonas Wilms