问题
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
回答1:
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:
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
来源:https://stackoverflow.com/questions/46658513/javascript-event-loop-clarification