Skip to content

event loop

Jorge Estanislao Barsoba edited this page Sep 2, 2021 · 2 revisions

Must-Knows - JavaScript - Event loop

In a nutshell, “It is what allows a JavaScript engine to perform non-blocking I/O operations, despite the fact that JavaScript is single-threaded, by offloading operations to the system kernel whenever possible”

JS concurrency model is based on it.

Components of a JS runtime

  • 1. Stack: Function calls form a stack of frames
    • Example:
      • Two functions
        • Function bar, which calls foo
        • Function foo
      • When calling bar, a frame is created with bar’s arguments and local variables
      • When bar calls foo, another frame is created on top of the 1st one
      • When foo returns, the top frame is popped out of the stack
      • When bar returns, the stack is empty
  • 2. Heap: Large unstructured region of memory where objects are allocated
  • 3. Queue:
    • List of messages to be processed
    • Each message has a function, which gets called to handle the message
  • 4. Event loop:
    • It’s just a while loop (that’s how it got its name!)
      while (queue.waitForMessage()) {
        queue.processNextMessage()
      }
      
    • queue.waitForMessage() waits synchronously for a message to arrive
    • queue.processNextMessage() pops the first message from the queue, and processes it completely, before any other one is processed (“run-to-completion”)
      • Once a function is running, it cannot be preempted
        • Unlike C#, where a function runs in a thread, and it can be stopped at any point by the engine, to run some other function in another thread
      • Downside is that if a message takes too long, the webapp is unable to process user interactions

To be more precise, the JS engine consists of the Stack and the Heap, and the JS runtime, which includes the engine, provides the Queue and the Event loop to make JS concurrent

Adding messages to the queue

  • In web browsers, a click on an element with a click event handler, will add a message to the queue
  • With setTimeout:
    • It has two arguments:
      • A message to add to the queue
      • Minimum time until the message will be pushed into the queue
    • If there is no other messages in the queue, and the stack is empty, the message gets processed after the delay; Otherwise, it will have to wait
  • Multiple runtimes: A web worker or an iframe has its own stack, heap and queue; And with method postMessage, one runtime can add messages to the queue of another runtime

Based on how the event loop works, JavaScript never blocks (if built correctly of course); I/O, like waiting for a database query to return, is typically performed via an asynchronous function and a callback, and the runtime can still process other things

Event loop in Node.JS

The event loop has the following phases:

In each phase, the event loop…

  • Has a FIFO queue of callbacks
  • Performs any operations specific to that phase
  • Executes the callbacks until the queue is empty or the max is reached
  • Moves to the next phase...

Phases overview

  1. Timers: executes callbacks scheduled by setTimeout and setInterval
  2. Pending callbacks: executes I/O callbacks deferred to the next iteration
  3. Idle, prepare: only used internally
  4. Poll: retrieves new I/O events; executes I/O related callbacks (all except the ones from phases i and ii)
  5. Check: executes callbacks scheduled by setImmediate
  6. Close callbacks: executes close callbacks such as socket.on('close', ...)

Sources

Clone this wiki locally