6

I was learning about JavaScript's event loop on the MDN doc. It mentioned that a message in the queue is run to completion, but at the end, it said that the event loop is never blocked. I don't really understand this. Isn't this a contradiction? Please help me understand the difference between them.

"Run-to-completion"

Each message is processed completely before any other message is processed. This offers some nice properties when reasoning about your program, including the fact that whenever a function runs, it cannot be pre-empted and will run entirely before any other code runs (and can modify data the function manipulates). This differs from C, for instance, where if a function runs in a thread, it may be stopped at any point by the runtime system to run some other code in another thread.

A downside of this model is that if a message takes too long to complete, the web application is unable to process user interactions like click or scroll. The browser mitigates this with the "a script is taking too long to run" dialog. A good practice to follow is to make message processing short and if possible cut down one message into several messages.

Never blocking

A very interesting property of the event loop model is that JavaScript, unlike a lot of other languages, never blocks. Handling I/O is typically performed via events and callbacks, so when the application is waiting for an IndexedDB query to return or an XHR request to return, it can still process other things like user input.

Boann
  • 48,794
  • 16
  • 117
  • 146
Ha0ran
  • 585
  • 5
  • 13
  • Maybe [this](https://www.youtube.com/watch?v=cCOL7MC4Pl0&ab_channel=JSConf) helps you understand – KooiInc Nov 20 '21 at 08:44
  • Or [even more clearer](https://www.youtube.com/watch?v=8aGhZQkoFbQ&t=25s&ab_channel=JSConf) – KooiInc Nov 20 '21 at 09:07
  • 1
    I guess the word "never" in "never blocks" is just not precise. JavaScript blocks sometimes, on user code. Do a do-while(true) loop and it blocks forever. – Wiktor Zychla Nov 20 '21 at 20:35

1 Answers1

6

You're right, the two citations contradict each other.

In the event loop, all messages are run-to-completion, as it is written in the first text, therefore they do block the event loop while they execute.

This is why timer2 won't execute before the loop in timer1 finishes in this example:

console.log('start');

setTimeout(() => {
  const startTime = Date.now()
  while(Date.now() - startTime < 3000);
  console.log('timer1 end');
}, 0)
setTimeout(() =>  console.log('timer2'), 0);

/*
start
-- three seconds later --
timer1 end
timer2
*/

The text saying "never blocks" is supposed to mean that, unlike many languages, most APIs that take long (or are polling something slow) are designed to not block the event loop for a long time, instead, instruct the JS runtime to handle the task in a background thread without blocking JavaScript, and pass back the results to JS when they're ready.

A much more accurate description of this would be that "although the event loop can be blocked by long-running code, most JS APIs are designed to avoid doing that".

FZs
  • 16,581
  • 13
  • 41
  • 50
  • 1
    It's often not the "long running code" but just waiting unproductively for an Io operation to complete. C's fread, which is taught to beginners, is a good example of bad design. – Wiktor Zychla Nov 20 '21 at 11:19
  • [Devil's advocate deliberately splitting hairs], actually... in most modern engines, JS is executed in a kind of sandbox where the event loop can tell "hey you spent more than *t* time in here, certainly something is going on" and it will give the hand to the user with this ""a script is taking too long to run" dialog" they talked about in the first quote. But I agree that's probably not what they meant in this second paragraph... and their 'exception' that does follow the quote is interestingly wrong for Firefox which does actually spin the event loop with `alert` and don't block it at all. – Kaiido Nov 20 '21 at 14:23
  • @Kaiido I agree with you on that "script taking too long" dialog thing. "*...Firefox which does actually spin the event loop with alert and don't block it at all.*" -- what are you talking about here? – FZs Nov 20 '21 at 22:14
  • If you go to the page where these quotes were taken, you'll see that the second one continues by saying that one exception is `alert()`. But FireFox does not block the event loop when JS is blocked through `alert()`, they keep it running and simply don't run user-land scripts, but they do run other tasks, for instance the rendering steps. – Kaiido Nov 21 '21 at 00:29