Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?
like image 815
kurtcorbett Avatar asked Apr 02 '15 20:04

kurtcorbett


People also ask

What is an event loop and callback queue and microtask queue?

Microtask Queue gets the callback functions coming through Promises and Mutation Observer. Callback Queue has lesser priority than Microtask Queue of fetching the callback functions to Event Loop. Microtask Queue has higher priority than Callback Queue of fetching the callback functions to Event Loop.

Is event loop single-threaded?

Event Loop uses Single Thread only. It is main heart of Node JS Platform Processing Model. Even Loop checks any Client Request is placed in Event Queue.

How does JavaScript work single-threaded with event loop?

The language itself is single-threaded, but the browser APIs act as separate threads. The event loop facilitates this process; it constantly checks whether or not the call stack is empty. If it is empty, new functions are added from the event queue. If it is not, then the current function call is processed.

How JavaScript works event loop stack and queue?

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.


1 Answers

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.

like image 199
Bergi Avatar answered Sep 20 '22 18:09

Bergi