6

I keep seeing explanations of the "Javascript Event Loop" (ie: browser JS runtime event loop) that don't seem plausible to me, and I'm hoping someone can provide some authoritative clarification.

My base asssumption is that the JS event loop is just like event loops we've been working with in UI frameworks for decades, something like:

  // [... some initialization ...]

  // The Event Loop
  while (true) {
    if (! EventQueue.isEmpty()) {
       event = EventQueue.pop_oldest_item();
       event.callback(event [or some other kind of args]);
    }
    // [... defer to other non-JS tasks...]
  }

But I keep seeing explanations (see below for examples) like this:

The event loop:

  1. Checks whether the (Javascript) call stack is empty.

  2. Checks whether the callback queue [AKA EventQueue] is empty.

  3. If call stack is empty and callback queue is NOT empty, then:

    a. Dequeue oldest callback queue item.

    b. Push that callback function onto the call stack (and no mention is made of calling that function.)

  4. Keep looping.

This obviously vaguely follows my assumed model above, but with two key and troubling differences:

A. Why would the event loop need to check that that the JS call stack is empty? Surely every time around the loop the call stack will be in the same state (whether that's completely "empty" is beside the point -- it doesn't need "checking"). Whatever function was called last time around will have returned, restoring the stack. So that part makes no sense.

B. Why would the event loop "push the callback onto the JS stack"? Shouldn't the event loop just call the function, thereby creating a legitimate stack frame, and a way to return from the function, not to mention actually executing the function?

So I would appreciate a clarification that addresses these explanations and why they are actually correct, or bolsters my strong suspicion that they are incorrect.


Example sources of these event loop explanations:

Philip Roberts: What the heck is the event loop anyway? At 14:00 https://youtu.be/8aGhZQkoFbQ?t=839

Typescript High Performance (book) page 83.

What is the Javascript event loop? http://altitudelabs.com/blog/what-is-the-javascript-event-loop/

Understanding Javascript Function Executions - Call Stack, Event Loop, Tasks & more https://medium.com/@gaurav.pandvia/understanding-javascript-function-executions-tasks-event-loop-call-stack-more-part-1-5683dea1f5ec

3 Answers 3

1

I think this comes from thinking of the event loop as if it’s some kind of parallel process to the main blocking code. That is, this misunderstanding is by the people who write those event loop explainers. My understanding is that the event loop runs in the same thread as the main code (talking about browser runtime, not nodejs), which means it can only poll the queue for new events when any blocking code has finished and returned. So what this means is that your event loop would not even be able to continue running until your blocking code has finished, which means that it doesn’t need to check “whether the (Javascript) call stack is empty”, because just the mere fact that event loop is running already means that the call stack “is empty”.

Sign up to request clarification or add additional context in comments.

2 Comments

So, am I right in thinking you basically agree with my critique? Or did you add something new that I perhaps missed?
I basically agree with you and think a lot of explainer articles out there are just dumb :D Our understanding is also shown in the pseudocode in MDN docs I think: developer.mozilla.org/en-US/docs/Web/JavaScript/…
0

This is my answer to your question:

JavaScript behaves in a single threaded and synchronous manner, so the event callback function will be executed after Global Execution Context pops off the execution stack. All the event will be added into the what called event queue.

After global execution context finish all the execution, JS engine will keep checking if there exist any event inside the event queue. If JS engine sees there is an event, then it will create a new execution context for callback function and push it on the execution stack.

In JS, each time you invoke a function, JS engine will create an execute context, which creates a private scope where anything declared inside of the function can not be directly accessed from outside the current function scope, and pushes on the top of the execution context stack. After the function finish executing, the execution context will be popped off.

2 Comments

This is my comment to your answer
I appreciate you answering, but I am not sure how this addresses my question. You affirm that there is an event queue -- this is not in doubt. And you describe how a function call works -- like in any language it involves a stack frame (here called an execute context). And something about the Global Execution Context popping off the stack -- which doesn't make sense. In short, you have not addressed my points "A" and "B". But thanks for the effort.
-2

Because of the asynchronous nature of some functions that are executed in the call stack (event handlers, setTimeout, http requests) messages (callbacks) from these operations can be added to the message queue at any time. This can happen while the main thread is still running functions in the call stack so the event loop needs to check to see if it is empty or not. Once empty then it will pull the next message from the message queue and throw it into the call stack. This cycle constitutes the essence of the event loop.

I made a video presentation that explains and demonstrates this process: https://www.youtube.com/watch?v=4xsvn6VUTwQ

2 Comments

As for part B - this is just how the Javascript runtime is architected. Functions are executed in the call stack, which is essentially the single thread of execution in Javascript. The event loop doesn't invoke functions directly rather it orchestrates the timing and order of message execution.
I appreciate your answering, but so far as I can tell your answer exactly demonstrates the issues I have with explanations of how the event loop works. What does it mean to "throw a message on the call stack"? The call stack contains context data for each call (arguments, local variables), while that call is being executed. How does that square with "throwing a message on the call stack" if that message is not part of an actual call, ie: invoking a function, which you claim is not something the event loop does.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.