The call stack is simply a data structure that keeps track of where we are in the program. Now, here comes the point where things slow down. If we can execute only one piece of code at a time, we need to wait for the called functions to finish before the later functions can be executed. This may not be a problem if our code consists of only simple operations like console.log, but image processing or network requests can take a long time. Is this a problem? Definitely. Because we are running our code on the browser, and nothing we do on the browser will be processed as long as the stack is not empty, literally freezing the browser.
So, what is the solution? Asynchronous calls. Let's take a look at the following code snippet.
When we start running the code from top to bottom, take a look at how the setTimeout function behaves. It appears in the call stack and makes a request to the Web API before leaving the call stack. When the request is successfully completed, the Web API adds the function to the callback queue and the result waiting in the callback queue appears in the stack when the call stack is empty. This process is essentially the same in both node and browser environments, except that C++ API is used in node instead of WebAPI. In the above diagram, the setTimeout function is given a parameter of 500ms. But what if we set it to 0ms? No, it would not be executed immediately. It would be added to the callback queue (or task queue) and executed after the call stack is empty.
Let's take a look at some other examples of situations we may encounter.
We have 3 setTimeout functions that can all be expected to run at the same time, i.e., 1 second later. However, these functions are added to the Web API and will not enter the callback queue until 1 second after they are added. Since queue elements will be added to the stack in order and the stack must be emptied first, we can be sure that they will run not 1 second later, but at least 1 second later.
Actually, asynchronous requests are queued before being executed, and we don't want this queue to grow indefinitely as it would slow down our program.
$.on("document", "scroll", dummy_function)
Let's imagine we have a code snippet like the one above, and every time we scroll, the dummy_function function will be called multiple times and added to the queue, causing an undesired situation called "flood". We can prevent this unwanted situation by ensuring that the request is made every few seconds.