{"id":11084,"date":"2020-09-11T10:30:43","date_gmt":"2020-09-11T14:30:43","guid":{"rendered":"https:\/\/www.carnaghan.com\/?p=11084"},"modified":"2023-10-14T23:14:38","modified_gmt":"2023-10-15T03:14:38","slug":"understanding-asynchronous-javascript","status":"publish","type":"post","link":"https:\/\/www.carnaghan.com\/understanding-asynchronous-javascript\/","title":{"rendered":"Understanding Asynchronous JavaScript"},"content":{"rendered":"\n

The term “asynchronous” is often associated with JavaScript, which can be a confusing concept, especially for beginners. This can become even more confusing because JavaScript is a synchronous language with asynchronous capabilities. In order to understand asynchronous development in general, we need to start with the difference between synchronous and asynchronous programming. In simple terms, executing one task or item at a time is often referred to as synchronous, while executing multiple tasks (or threads) at a time is referred to as asynchronous.<\/p>\n\n\n\n

JavaScript is synchronous, single-threaded, and blocking language. It is synchronous, meaning it can execute one statement at a time. It is single-threaded, meaning, it has a single “call stack”<\/a>. We will discuss blocking later, but for now let’s take a look at how JavaScript executes code:<\/p>\n\n\n\n

function fun(){\n    console.log(\"Executed in the function\");\n}\n\nconsole.log(\"Executed first...\");\n\nfun();\n\nconsole.log(\"Executed last...\");\n<\/code><\/pre>\n\n\n\n

It is a very simple code, but we need to dig a little bit deeper and look at execution context and the call stack. An environment where the JavaScript code is evaluated and executed is called the Execution context. There are two types of execution context<\/a> in JavaScript, Global Execution Context (GEC), and Functional Execution Context (FEC). The execution contexts are stored in a stack called the call stack. There is only one call stack in JavaScript because it is a single-threaded programming language. The call stack is based on LIFO, meaning, Last In First Out. Let’s break down the above code to better understand the call stack.<\/p>\n\n\n\n

1. When the code is executed, a global execution context is created which is the first entry in the call stack.<\/p>\n\n\n\n

main() -><\/code><\/pre>\n\n\n\n

2. Next, console.log(“Executed first…”) is pushed into the stack.<\/p>\n\n\n\n

main() -> console.log(\"Executed first...\")<\/code><\/pre>\n\n\n\n

3. After its execution is completed, it is popped out of the stack.<\/p>\n\n\n\n

main() -><\/code><\/pre>\n\n\n\n

4. After that, fun() is pushed into the stack.<\/p>\n\n\n\n

main() -> fun() -><\/code><\/pre>\n\n\n\n

5. Now, fun() is executed. console.log(“Executed in the function”) is pushed in the stack.<\/p>\n\n\n\n

main() -> fun() -> console.log(\"Executed in the function\") -><\/code><\/pre>\n\n\n\n

6. After the console statement is executed, it is popped out.<\/p>\n\n\n\n

main() -> fun() -><\/code><\/pre>\n\n\n\n

7. Function execution ends and fun() is popped out.<\/p>\n\n\n\n

main() -><\/code><\/pre>\n\n\n\n

8. Next, console.log(“Executed last…”) is pushed into the stack.<\/p>\n\n\n\n

main() -> console.log(\"Executed last...\") -><\/code><\/pre>\n\n\n\n

9. console.log(“Executed last…”) executes and is popped out.<\/p>\n\n\n\n

main() <\/code><\/pre>\n\n\n\n

10. Program execution is completed, so the main() is also removed from the stack.<\/p>\n\n\n\n

The purpose of the above demonstration was to illustrate how JavaScript executes code line by line and only moves to the next line when the previous command has completed its execution. This is synchronous JavaScript. I also wrote an earlier article which explains the call stack in context of synchronous execution in more detail see: JavaScript Call Stack – Ian Carnaghan<\/a>.<\/p>\n\n\n\n

In the example, nothing was blocked, but there can be scenarios when the call stack is blocked due to reasons such as calling APIs, which can block the call stack. Network requests generally take time, therefore blocking the call stack:<\/p>\n\n\n\n

function APICall(url){\n    \/\/ some operation\n}\n\nAPICall(url)\n\nconsole.log(\"Execution ends here...\");\n<\/code><\/pre>\n\n\n\n

In the above code, the “APIcall” function is calling an API. First, the APICall function completes execution followed by, console.log(“Execution ends here…”). Since the APICall function is making an API call, it can take some time to complete. Therefore, the execution is blocked at this point and the console statement will not run until APICall is completed. This illustrates the downside of synchronous programming. In asynchronous programming, execution would not stop. It would not wait for the APICall function to complete the execution, instead it would move further, executing the console statement. One way to achieve this is through the use of callback functions.<\/p>\n\n\n\n

Callback functions<\/h2>\n\n\n\n

JavaScript functions are considered first-class functions<\/a>. A JavaScript function can be assigned to a variable, passed to another function as a parameter, and also it can be returned from another function. You can learn more about this here<\/a>.<\/p>\n\n\n\n

A function passed to another function as an argument is known as a callback function. Here’s a simple example:<\/p>\n\n\n\n

console.log(\"Executed first...\");\n\nsetTimeout(() => {\n    console.log(\"Executed after 5 seconds...\");\n  }, 5000);\n\nconsole.log(\"Executed last...\");\n<\/code><\/pre>\n\n\n\n

Normally, console.log(“Executed first…”) should be executed first, followed by the setTimeout function, and finally console.log(“Executed last…”). But the above code is not synchronous, it is asynchronous. To understand this better, take a closer look at the setTimeout function.<\/p>\n\n\n\n

setTimeout(() => {\n    console.log(\"Executed after 5 seconds...\");\n}, 5000);\n<\/code><\/pre>\n\n\n\n

The first parameter of the setTimeout function is a callback function and the second parameter is 5000, meaning 5 seconds. This means, the callback function will be executed after 5 seconds. The output of the code should look like this:<\/p>\n\n\n\n