What is this “EventLoop” in JavaScript?

We’ve all heard about it – The EventLoop. How I knew about any of it is that it had something to do with callbacks, and this notion of asynchronous code. Quite recently I followed one JS-Conf which happened in 2014 (Yes, it’s been a while) and got a better understanding of this mysterious event loop.

Asynchronous Vs. Synchronous

Rather than talking about Asynchronous code, I’ll start with Synchronous code which we are more familiar with. Synchronous behavior is what we do expect from our codebase. Take this example.

https://gist.github.com/dasunpubudumal/be01215be615bbfaffcfc01d8aa920d1

In Computer Science, there is this thing (A data structure) called a “Stack”. Well, there are two major data structures when we’re talking about memory – Heap and Stack – but we will not need the heap here. So we’ll focus on the stack.

For each of these functions, according to the order of execution, a stack frame is created inside the stack.

Here, the stack grows upwards. And note that when an execution of a function is complete, the stack pops out that particular function out.

Notice the behavior of execution. The codebase is executed as per the order we have written it. But imagine that we had a time consuming function, say, performing an I/O operation (Maybe fetching from a database). Usually those operations take quite a little while than dealing with in-memory operations. If you’ve ever read some of the articles about the notion of Non-blocking or Asynchronous I/O, you might have seen the demonstrators use this particular setTimeout API. But the surprising fact is, if you just take a look at the code of Chrome runtime (V8), there is no API for this. So from where does this come??

Well as it turns out, the browsers offer some other Web-API’s than just the JavaScript Runtime.  setTimout resides in those APIs.

What does that got to do with anything? Well, I’m gonna use this function to demonstrate Asynchronous behavior of JavaScript. That’s why.

 

https://gist.github.com/dasunpubudumal/4088d21676b2ff5e9543cf97cd957bbe

If you run this, you’ll get this output.

Screenshot from 2018-07-08 20-02-16.png
Output from Chrome Console

You’ll notice that Chrome Runtime has done some weird thing – it has run the last code piece before the middle!! The meaning of Asynchronous code is nicely demonstrated from this example – that is, unlike Synchronous code, it does not run in the way we execute it. It may jump here and there but it will eventually, execute every single line of your codebase.

Blocking Vs Non Blocking

Think of a traffic – you’re blocked in a traffic. You can’t work your way along the road if you’re in a traffic jam. If you execute a piece of code which in turn, puts your execution into a jam, that is called a blocking piece of code. setTimout( () => {}, 2000 )  is a blocking operation. It halts your code for approximately 2 seconds.

If you come from a CS background, you might have heard of the notion of Threads. A thread is a lightweight process which resides inside a process. There can be multiple threads per a process (But not vise-versa). Thus, the process can be divided and executed in multiple threads. But do not make the mistake of thinking of this as parallel processing – that is running multiple processes concurrently, which is not done using threads.

So, using threads, can’t we delegate this time consuming blocking operations to another thread (Other than the main thread)??

Well, apparently, you can. But, heed this. JavaScript is Single Threaded. So you’re not working in multiple threads! Well, there goes our intelligence!

“EventLoop”

Remember those Web-APIs I mentioned about? Well, those come in handy at this time. What the Runtime does is, when it encounters such blocking operations, it delegates these operations to web-APIs (Whose implementations are hidden from you – for an example in NodeJs, these implementations are done in C++) , they are processed inside those implementations, and queued in a Task Queue. When the operations in the stack are done (i.e. when the stack is empty), functions in the task queue are executed.

Hopefully, this might give you some insights on how this thing works

What is explained in bold in the previous paragraph, is the job of the EventLoop. That is, putting the stuff which are in the task queue (This is also called the Callback queue) to the task queue.

Engineers are stupid.

Alright – we engineers like to do stupid stuff. Take this example.

 

 

 

 

 

https://gist.github.com/dasunpubudumal/b039d572e25a02bb0e06c200b4ff448f

Got what I’ve done? I’ve made the timeout 0. Why? I don’t know.

So what happens if we do this? Well, the Runtime doesn’t know that it needs to wait 0 seconds (i.e. it does not have to wait), because runtime is unaware of the setTimeout API! What it knows is that it is a time consuming operation and thus, it will delegate this to the web-APIs. Soon after the web APIs process this (Which takes 0 seconds) it will get queued and will not execute until the stack is complete. Thus, the same result will appear.

Screenshot from 2018-07-08 20-02-16.png
Same result! How unfortunate 😦

“Callbacks”

Callbacks are inherently asynchronous operations which are needed to be put on to the callback queue. The first parameter in setTimout itself is a callback! This example is directly copy pasted from mysql module in npm which clearly explains the need for a callback when performing database queries.

 

 

 

 

https://gist.github.com/dasunpubudumal/81201965389614e204e04eb78254bdd7

Notice how the callback is used to get the results field.

Dealing with Asynchronous operations

Callback is one way of dealing with this. Another way is the Promises API in Javascript. In promises you have notions of resolve and reject where those indicates the success and failure of each promise you make. This is an example for Promises API.

 

 

https://gist.github.com/dasunpubudumal/cc2832ee3b2fc06c623999df80bb59eb

Another way to deal with this async behavior is async – await. 

 

 

 

https://gist.github.com/dasunpubudumal/e96ca274ba484dad38f47d90870ff14e

When we include await the execution will wait until that particular operation is done.

So, that’s it for event loop and asynchronous stuff! Do some research for this – eventloop is used in Java when it comes to web sockets – where the speed is key. There is a handy library called Netty for Java which deals with Asynchronous I/O – and the notions of callbacks are present there as well.

Leave a comment