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:
Checks whether the (Javascript) call stack is empty.
Checks whether the callback queue [AKA EventQueue] is empty.
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.)
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
The Event Loop has one simple job — to monitor the Call Stack and the Callback Queue. If the Call Stack is empty, the Event Loop will take the first event from the queue and will push it to the Call Stack, which effectively runs it. Such an iteration is called a tick in the Event Loop.
The event loop utilizes three major components, Call Stack, Event Queue, and WebAPIs/C++ APIs. It manages function calls in a way that asynchronous events would go into the event queue and will be called only after the call stack is empty.
The event loop will take calls from the promise queue first before processing the callback queue. Let's have a look at an example: console. log('a'); setTimeout(() => console. log('b'), 0); new Promise((resolve, reject) => { resolve(); }) .
The Event Loop takes the timer with the shortest wait time and compares it with the Event Loop's current time. If the wait time has elapsed, then the timer's callback is queued to be called once the call stack is empty. Node. js has different types of timers: setTimeout() and setInterval() .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With