How does JavaScript run asynchronously?

Tram Ho

“JavaScript runs asynchronously”. If you’ve ever worked with JavaScript, you will hear it often. But even though you hear a lot, not everyone can claim to have understood it. If you are one of them or want to take a different look at asynchronous JavaScript, let’s get started.

JavaScript Engine

One thing you need to understand is that JavaScript itself is a synchronous language, like Ruby, PHP, Python … When running on Client-side or Server-side, if you need a program to translate and execute code and it’s called a JavaScript Engine . There are many JavaScript Engine used on different browsers or environments, but they have the main components are Memory Heap and Call Stack: Here are their main functions:

  • Memory heap : Tasks are allocated and used to free memory for the program.
  • Call Stack : A data structure that contains executable program tasks.

When running synchronously

Before learning about asynchronous JavaScript, let’s take a look at how JavaScript Engine synchronization will work:

Above is a program description describing the tasks usually performed in the morning. It won’t be hard for you to guess what will be logged off the screen. However, let’s take a look at the image below to get a better idea of ​​what happened: Call Stack works similarly to a LIFO (Last In – First Out) data structure. The code to run synchronously will be put on the stack and the task is put into the last will be executed first. To accomplish this, we must resort to another JavaScript Engine component, the Event loop . We will see it again later in the article.

When running asynchronously

JavaScript is a single threaded language, meaning that there is only one Call Stack in a program. For heavy and time-consuming tasks, the entire program at that time will be blocked until the task is completed. You may have encountered this problem when sending an ajax request, running an infinite loop … now we can not manipulate anything on the browser anymore. To solve this problem, the JavaScript Engine has provided APIs to run asynchronous JavaScript code.

Callback queue

To be able to run asynchronously, JavaScript uses another component called Callback Queue. You can imagine Callback Queue is like a waiting room in a restaurant. For customers who have booked (Synchronous), will be served priority in Call Stack. And when you go to the restaurant without notice, you may have to do a certain procedure (Asynchronous) and sit waiting before being served. However, in a lounge there will be close customers or VIP customers will be served first even though they may not be the first to come.

Callback Queue is similar, each task will have different priority. The task with the higher priority will be put on Call Stack first. The priority order in Callback Queue is: Microtask > Macrotask > Render Queue, respectively . In particular, Render Queue is the task related to rendering and updating the view of the browser so in this section we only learn about Microtask and Macrotask.

Macrotask

Microtask is a FIFO (First In – First Out) data structure, it usually stores tasks performed by web APIs such as setTimeout, DOM events … Let’s take a look at the example below to understand. more about it

Before running the above code, guess what will be logged off the screen? If it’s not what you expected, let’s take a look below to see what happened: Methods like setTimeout , setInterval or DOM operations are all APIs provided by a browser. As in the above example, getUp() and haveBreakfast() are both functions that run in sync so it will be immediately included in the Call Stack. Particularly, the makeCoffee() function uses setTimeout so its content will be included in web APIs for implementation. Here the web APIs will process and set a timer, when time is up, this task will be pushed down to the specific Callback Queue in this case Macrotask. When the Call Stack is empty, the tasks under the Callback Queue are removed and put on the Call Stack. Once again, the Event loop will be the one who helped us through the whole process.

Microtask

Similar to Macrotask but with higher priority, meaning that the tasks stored in Macrotask are only executed (put on Call Stack) when Microtask is empty. These are usually processing tasks that involve Promise or when using the queueMicrotask function. We have an example with the participation of both Microtask and Macrotask:

Probably not difficult for us to get the correct answer for what happened. But take a look at the image below to make it easier to imagine it:

  • The first makeCoffee() function is called and similar to the above example, the processing of this function is done by webAPIs and is immediately taken down to Macrotask, the makeCoffee() function is done and removed from Call Stack.
  • The haveBreakFast() function is immediately included in the Call Stack. This function only creates and saves a task into Microtask, then it is also removed from CallStack.
  • Now getUp() just been called and since this is a synchronous function, its handle will be included in CallStack.
  • After the getUp() function is finished, CallStack is empty, the tasks in Microtask will be posted back to CallStack.
  • When all the Microtasks have been processed, Call Stask and Microtask are now empty, it is time to perform the tasks that are stored in Macrotask.

Event loop

Event loop is a very important concept in JavaScript. In another article I will talk more about it, but in the framework of this article, after the previous examples, we can also summarize how the Event loop works as follows:

  • First, it will scan through CallStack, if Call Stack still has uncompleted tasks, it will remove the top task and execute it and remove that task from Call Stack.
  • If the Call Stack is empty, the Microtasks will be placed on the Call Stack in order when they are pushed in.
  • Once all the Microtasks have been successfully executed, that is when the Macrotasks are executed, similar to the microtasks.

Summary

We have just gone over how JavaScript works when synchronous or asynchronous code is run. While this is just an overview of what JavaScript actually did, hopefully it will help you understand and make it easier to imagine what happened. See you in the other posts.

Share the news now

Source : Viblo