Skip to content

Instantly share code, notes, and snippets.

@khanh-bes
Forked from jesstelford/event-loop.md
Created December 22, 2020 09:43
Show Gist options
  • Select an option

  • Save khanh-bes/e0c6f332ff803e596329ced8527382e1 to your computer and use it in GitHub Desktop.

Select an option

Save khanh-bes/e0c6f332ff803e596329ced8527382e1 to your computer and use it in GitHub Desktop.
What is the JS Event Loop and Call Stack?

Given the code

setTimeout(() => { 
  console.log('hi')
}, 1000)           

The Call Stack, Event Loop, and Web APIs have the following relationship

        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  |                   |              | |               |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

To start, everything is empty


        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
> setTimeout(() => {  | setTimeout        |              | | timeout, 1000 |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

Then the first line is executed. This pushes the function execution as the first item onto the call stack.

Note that the Call Stack is a stack; The last item pushed on is the first item popped off. Aka: Last In, First Out. (think; a stack of dishes)


        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
> setTimeout(() => {  | setTimeout        |              | | timeout, 1000 |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

Executing setTimeout actually calls out to code that is not part of JS. It's part of a Web API which the browser provides for us. There are a different set of APIs like this available in node.


        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  |                   |              | | timeout, 1000 |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

setTimeout is then finished executing, while the Web API waits for the requested amount of time (1000ms).

The Call Stack is empty now.


        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  |                   | function   <-----timeout, 1000 |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

Once the timeout has expired, the Web API lets JS know by adding code to the Event Loop.

It doesn't push onto the Call Stack directly as that could intefere with already executing code, and you'd end up in weird situations.

The Event Loop is a Queue. The first item pushed on is the first item popped off. Aka: First In, First Out. (think; a queue for a movie)


        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  | function        <---function     | |               |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

Whenever the Call Stack is empty, the JS execution environment occasionally checks to see if anything is Queued in the Event Loop. If it is, the first item is moved to the Call Stack for execution.


        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  | function          |              | |               |
>   console.log('hi') | console.log       |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

Executing the function results in console.log being called, also pushed onto the Call Stack.


        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  | function          |              | |               |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |
> hi

Once finished executing, hi is printed, and console.log is removed from the Call Stack.


        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  |                   |              | |               |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

Finally, the function has no other commands to execute, so it too is taken off the Call Stack.

Our program has now finished execution.

End.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment