Why is the JavaScript Event Loop Hard to Understand with Async Code?

Hello

I am learning JavaScript on Exercism and recently got confused by how the JavaScript event loop works. :innocent:When I use things like setTimeout, Promises, and async/await together, the order of the output in the console is not always what I expect. :blush:

This makes me feel like I don’t fully understand what’s happening behind the scenes.

For example, I thought that setTimeout with zero delay would run immediately, but a Promise still finishes first.

I later read that this is because Promises go in the microtask queue, while timeouts go in the macrotask queue. :thinking:Even though I read about it, I still find it tricky to remember and explain clearly. Checked JavaScript execution model guide for reference.

So, I want to ask: how do you learn and remember the event loop in a simple way? I know many people begin by asking what is javascript but for me this is the next important step to get better. :innocent:

Any easy examples, tips, or good resources would be really helpful. :thinking:

Thank you!!

For the setTimeout, I remember that whenever I add something to that, I’m adding to a queue. And that queue won’t run until whatever the main code that’s running has finished. So I think of setTimeout(..., 0) as “Add this to a queue to run immediately (0) once the current code is finished”.

For async/await/promises, the whole point really is that you don’t need to think about when they run. In fact, you actively don’t want to anticipate that. You maybe want to think of them more like being a setTimeout(... rand(0, 10)), so the code might run (or complete) at sometime in the future and you have no idea when.

From a technical perspective, I think of three things:

  1. The current running code (this takes priority)
  2. Anything that happens on a timer (setTimeout, setInterval, requestAnimationFrame, etc)
  3. Code that’s waiting to finish (e.g. Promises waiting to resolve).

Then:

  • (1) just chugs along until it finishes
  • Then the first thing ready in (2) or (3) becomes (1) and we restart the sequence.

It’s more complex under the scenes, but if you think of it in terms of “there’s some code running and then there’s things waiting to run”, you’re basically going to have 99.9% of use-cases covered much more simply.

1 Like

A event loop visualiser may help:

https://www.jsv9000.app/?code=c2V0VGltZW91dChmdW5jdGlvbiBhZnRlcjBtcygpIHsKICBjb25zb2xlLmxvZygiQSIpOwp9LCAwKTsKClByb21pc2UucmVzb2x2ZSg0Mik7ClByb21pc2UucmVzb2x2ZSgpCiAgLnRoZW4oZnVuY3Rpb24gcHJvbWlzZVRoZW4oKSB7CiAgICBjb25zb2xlLmxvZygiQiIpOwogIH0pCiAgLnRoZW4oZnVuY3Rpb24gcHJvbWlzZVRoZW5DaGFpbigpIHsKICAgIGNvbnNvbGUubG9nKCJDIik7CiAgfSk7CgpzZXRUaW1lb3V0KGZ1bmN0aW9uIGFmdGVyMW1zKCkgewogIGNvbnNvbGUubG9nKCJEIik7Cn0sIDEpOwpzZXRUaW1lb3V0KGZ1bmN0aW9uIGFmdGVyMG1zQWdhaW4oKSB7CiAgY29uc29sZS5sb2coIkUiKTsKfSwgMCk7CgoKUHJvbWlzZS5yZXNvbHZlKCkKICAudGhlbihmdW5jdGlvbiBwcm9taXNlVGhlbkxhc3QoKSB7CiAgICBjb25zb2xlLmxvZygiRiIpOwogIH0pOwo%3D

Try to figure out the logs BEFORE you press run (and then press step / auto step).

BFC ADE

I think the hardest thing for people to grasp is that in this visualiser that the 1 ms call still happens before the next 0 ms call. You can change it to 10000 (10 seconds) to make it work as expected.

To add to the explanation by Jeremy:

  • promises try to execute as “soon as they are ready”. There is never a timer associated. This is why they go into the microtasks list and this is why I don’t call this “scheduling”, they are queued to be executed asap. A promise that does not do I/O (read from disk, query the interwebs, etc.) or has a manual delay (setTimeout(resolve), requestAnimationFrame(resolve), etc.), will always “instantly” be ready, and thus execute as soon as possible.
  • setTimeout (and setInterval etc.) are timers. They do not mean “execute after x ms”. They mean: “I want x ms to pass before I execute”. This is always scheduling. It cannot pick up something from the scheduled list until the queued tasks are done.

I think if you separate queuing from scheduling, it becomes easier!

1 Like