Async JavaScript

JavaScript

JavaScript is a single threaded language, meaning it only does one operation at a time. So JavaScript could not calculate a massive computation heavy formula for time travel and at the same time also calculate the purpose of existence. It would first have to figure out the time travel, and after that tell you the purpose of existence (“42” is the answer, I check already for you). This leaves us with a problem, how can we continue loading a page while making a request to a database sever in the background that is very slow? The JavaScript function waiting for the reply from the database server would block all other code form executing until it received a reply.

Trick Question!

So yes, JavaScript is a single threaded language. However, the JavaScript runtime environment (V8, which is Chrome for example) is not single threaded. So basically this is a technicality that allows JavaScript to by asynchronous while also still being a synchronous language.

Interpreted

JavaScript source code is interpreted, read and executed line by line. However, the V8 runtime does compile it into machine code before executing it to increase performance. JavaScript is still considered interpreted even when using V8 by most people, though there is some disagreement.

Hoisting

When JavaScript is executed it will first hoist variables and function declarations to the top of their scope before the code is executed. So let carName = "Viper" will be hoisted to the top as “undefined”. Only function, const, and let declarations are hoisted, so if a variable is declared such as let myCar; and later on in the code initialized myCar = "Civic" the declaration is hoisted only. So if you try and get the value of myCar in your code before reaching the initialization it will return undefined. Things declared with the var keyword are hoisted as undefined even if they are initialized at the same time. Function expressions are not hoisted.

JavaScript places all variables in the current execution context into the memory in the heap section before it begins execution of the code. Each variable gets a unique identification address in the memory, and it is stored with it’s value.

Call Stack

The call stack is a LIFO Last In First Out, the last item added in the current execution context is the first out. When a script is first executed, a main/global execution context is created and pushed onto the currently empty call stack. Now as the JavaScript code is executed line by line, each time it reaches a function call it creates a new execution environment for that function and places it onto the top of the call stack. Now, if that function calls another function inside of it, a new execution environment will be created just for that function and places onto the top of the call stack. If that function does not call a function, it will excute and be removed from the call stack, and the 2nd function added will now finish and also be removed from the call stack, until it is back down to the global execution environment.

Finally

So with all of that it still seems like JavaScript has to be run one step at a time. Well, kind of! You can pass a function to the Web API’s that the browser provides. Some functions are automatically passed, for example the setTimeout() is an example of a function that is automatically passed to a Web API. So the setTimeout function might have a 30 second delay. When the JavaScript execution reaches the setTimeout function, it will remove it from the call stack and pass it the Web API responsible for handling it. The call stack next moves onto the next function call, forgetting all about the function is passed to the Web API.

The browser is not responsible for handling the setTimeout function. It keeps track of the time, and when 30 seconds is reached it is placed onto something called the callback queue.

As a side note, the setTimeout method is not part of the JavaScript spec. It is provided by the browser and Node.js. The JavaScript engine does not have a clue that the function is not supposed to be run immediately, it just knows to pass it on to the Web API.

https://developer.mozilla.org/en-US/docs/Web/API take a look here for some of the Web APIs the browser has available for use.

Callback Queue

The callback queue is what the call stack checks if it no longer has any frames left on the stack. The event loop refers to this. If the call stack is empty, the event loop keeps running and checking the callback queue to see if anything has been added. If there is something in the callback queue, the event loops places it onto the call stack.

Web APIs

So what functions get offloaded onto the Web APIs? setTimeout() is one, any event listener as well such as click. That makes sense, otherwise the code would stop once it reached something waiting for a click and not move on until the click event happened. They take a callback function which runs once the condition is met. Callbacks are not async by default, in fact most are not.