DEV Community

Reggie Peterson
Reggie Peterson

Posted on

What Is the Event Loop?

check out the original post @ jayess.lifesandwich.co

It's mystical. Maybe you've never heard of it. If you're a developer who deals with browsers / http requests at all, chances are you've utilized it. It's what allows setTimeout to work, allow promises to be made, and how async/await is handled.

But First; JavaScript Engines

1) Browsers work on the web.

2) The web uses JavaScript.

3) Therefore, Browsers have JavaScript engines (to run the javascript)

Chrome's JavaScript engine is called V8. The same V8 Node.js is built on.

V8 is a single threaded execution engine. Single threaded meaning one call stack. Execution engine means, well, it executes the code.

V8

V8 has two main components: a memory heap & a call stack.

Memory Heap

This isn’t relevant enough to get into details, but the memory heap handles how & where the JavaScript gets stored. if you create a function called helloWorld and then want to use it later, the memory heap is what stores it and remembers where it is so when you want to use it, it works. That’s basically it.

Call Stack

A call stack is a data structure that allows functions to be added or removed from the top.

Since JavaScript & V8 are single threaded, there is just one call stack in V8. Whenever we perform an action/function in JavaScript, that thing is pushed onto the call stack, where it will run to completion and then be popped (or removed) off the top.

If the function called contains another function call, that will be pushed onto the call stack on top of the current call. This will continue until all code/calls have been executed and they will be removed one by one from the top.

Back to the Event Loop

Since JavaScript can only do one thing at a time, anything that needs to or should be done asynchronously must rely on functionality provided by the browser itself. Most browsers have browser APIs to handle the actual request, and then use a task queue and event loop to determine when it should be done.

A simple example

1) The browser receives the Javascript source code you wrote & interprets it

2) While the browser is executing the code, if it encounters a browser API such as a http request, it will push it onto the stack, begin a new, separate process of retrieving the response, and pop the call off of the stack

3) The browser will continue executing the code as before

4) Once the separate process is complete (ex. http request) it is sent to a task queue.

5) The response will wait in the queue until the event loop determines the call stack in empty* and will push it to the call stack, where the callback / promise / whatever was waiting is executed

6) After execution, it is popped off the stack and execution continues as normal or repeats these steps as needed.

Now here is the part you came for

So What is the Event Loop?

The event loop is a programming construct that checks the call stack and, when empty* will push the next waiting callback or promise in the queue to the call stack.

That's it.

It's a little program that directs the flow of traffic from asynchronous requests (promises, setTimout, http requests) back into the main flow of the one and only JS call stack.

** Asterisk **

There are not one, but two queues:

A microtask queue for promises.

A task queue for everything else.

You should also know that the event loop prioritizes microtasks above regular tasks.

This means that a normal task response waiting in the task queue will be pushed onto the call stack after the call stack is empty. As in, no more things to fire.

Here is a tool with a cool visual to show you how this works (sorry, no microtask queue)

However, this isn't the case for microtasks. Microtasks will fire in between code finishing and more code starting.

For example:

If you had three console.logs and a setTimeout set to 0ms with an function call in it, you would get normal synchronous code execution all the way from top to bottom and then after the console.logs were completed, the setTimeout function call would run.

But with microtasks such as promises, assuming your promise is at the top of the file above the console.logs, it would fire as soon as it could. At the end of the file, after the first console.log, after the second console.log, etc. It doesn't care. as soon as something is popped off the stack, and as normal execution is about to continue, all the microtasks in the microtask queue slide into the spot on the call stack and they won't let code continue running until ALL OF THEM are complete.

This is opposed to normal tasks in the task queue running one at a time, one per event loop cycle.

Got it?

Cool. That was easy.


check out the original post @ jayess.lifesandwich.co

Top comments (0)