How are the Event Loop, Callback Queue, and Javascript’s single thread connected?
Asked Answered
V

1

24

GENERAL GOAL

I’d like to know how the following pieces of a javascript environment interconnect as a system.

  • Javascript Engine
  • Event Loop
  • Event Queue

We can limit this to a browser environment since node has been covered in another article (here)

THINGS I (believe to) UNDERSTAND:

  • Javascript is single threaded and therefore only has one callstack.

  • Javascript environments provide only a few functions that are truly asynchronous. These may include setTimeout(), setInterval(), and I/O function(s).

  • A developer cannot create their own asynchronous functions without using one of these.
  • Javascript itself runs synchronously but through it’s async functions can callback the would-be blocking functions once the current callstack is clear.

EXAMPLE:

      console.log(‘Sync code started…’);

      setTimeout(function asyncLog() {
           console.log(‘Async function has completed’)
      }, 2000);

      console.log(‘Sync code finished…')

EXAMPLE STEPS:

( Please correct steps if I’m wrong )

  1. ‘Sync code started…’ is logged
  2. setTimeout is added to stack but immediately returns control
  3. setTimeout is sent to a different ‘thread’…’worker’? outside of javascript’s single thread to count the 2000 milliseconds
  4. ‘Sync code finished…’ is logged
  5. After 2000 milliseconds asyncLog() is pushed to the Event Queue
  6. Because the callstack is clear the Event Loop checks the Event Queue for pending callbacks
  7. asyncLog() is removed from the queue and pushed to the stack by the Event Loop
  8. 'Async function has completed’ is logged
  9. callstack is now clear

QUESTIONS

These don’t need to be answered one by one if someone could produce an overview of the steps of how and where async functions (such as setTimeout) go from the time they first hit the callstack to when they are called back to the callstack.

  1. On step 3, who produces this new thread? Is it the browser?
    • This new thread is being blocked correct?
    • What happens if you have a loop that creates 1000 setTimeouts. Are 1000 ‘threads’ created?
    • Is there a limit to how many threads can be spawned at a time?
    • When new thread finishes executing, how does it end up on the queue?
  2. Who supplies the Event Queue?
  3. Who supplies the Event Loop?
    • Does the event loop poll the Event Queue?
    • Is the javascript’s thread aware of an event loop? Or does the Event loop just push things onto the stack?
    • How does the Event loop know when the stack is clear?
Visualize answered 2/4, 2015 at 20:22 Comment(0)
H
14

Your understanding and your example seem to be basically correct. Now, to your questions:

On step 3, who produces this new thread? Is it the browser?

Yes. It is basically the thing that supplies the implementation for those "truly asynchronous" functions. IIRC, setTimeout is implemented in JS engines directly, while networking IO would be definitely the browser's responsibility - but it doesn't really matter who creates them. In the end, in your "browser environment" it's always some part of the browser.

This new thread is being blocked correct?

Yes. No. It depends on the work that needs to be done, i.e. which async function you called. Some may require spinning of a new thread, but for simple timeouts I'm pretty sure that a non-blocking system call is used.

What happens if you have a loop that creates 1000 setTimeouts. Are 1000 ‘threads’ created?

Possible. Unlikely, though. I'd assume for those async actions that really require their own thread, a thread pool is used, and requests are queued. The size of this pool might be hidden in the bowels of your browser's configuration.

Is there a limit to how many threads can be spawned at a time?

That would be controlled by the OS.

When new thread finishes executing, how does it end up on the queue? Who supplies the Event Queue?

Basically, the last action of each such thread is to put its result in the event queue.

Who supplies the Event Loop? Does the event loop poll the Event Queue?

I'd say that's an implementation detail, whether the loop polls the queue or the queue drives the loop iterations.

Is the javascript’s thread aware of an event loop? Or does the Event loop just push things onto the stack?

I'd say that the javascript runs in the event loop thread. The event loop just repeatedly pops events from the queue and executes their javascript.

How does the Event loop know when the stack is clear?

The event loop calls the javascript execution - so the stack is clear when the javascript returns.

Hexone answered 2/4, 2015 at 21:37 Comment(5)
It has taken me a while to realize that these are good answers to my questions. I feel like some nice graphics of how the browser handles the JS Engine would benefit the community greatly. Phillip Roberts talk on the event loop is very informative in many of these aspects as well. youtube.com/watch?v=8aGhZQkoFbQVisualize
hi I've got question about the async part 'A developer cannot create their own asynchronous functions' in original post, if you can have a look it will be much appreciated: #53920015Audubon
@Audubon Yes, only native functions can put an asynchronous callback on the event loop queueHexone
+Bergi thank you very much and wish you a merry Christmas!Audubon
MDN has an article called Concurrency model and Event LoopMarkettamarkey

© 2022 - 2024 — McMap. All rights reserved.