Understanding Technical concepts in JavaScript
One can always be a great driver without knowing how the automobile system operates.
Similarly, you can be a good developer without understanding the inner workings of the JavaScript language.
In this article, we will understand the difference between asynchronous and synchronous operations in JavaScript.
Also, we will understand what meaning of this popular definition of JavaScript as a single-threaded and non-blocking language.
Now, just like a sailor does not need to know how the ship engine works in order to sail his ship onshore, we don’t need to know how JavaScript works in order to write software.
There are many web developers who built good websites but to be a great and outstanding web developer, you need to pay close attention to the technical aspects of the language.
What is a program?
basically, a program is a set of instruction that tells a computer what to do in a language which the computer understands.
These instructions come in the form of many different languages such as C++, Java, JavaScript, HTML, Python, Ruby, and Rust.Technically, a program allocates memory, read and executes commands.
All browsers support the JavaScript engine which allows JavaScript codes to be executed in the browser.
Browsers and their JavaScript engine
- Google Chrome has the V8 engine.
- Firefox has the Spidermonkey engine
- Safari has the Nitro engine (also called JavaScript Core)
- Edge has the Chakra as its engine.
- and many others exist as well.
All these engines implement the ECMA ES-262 standard, also called ECMAScript, the standard used by JavaScript.
The JavaScript engine consist of two parts which includes:
- The Call Stack
- The memory heap
Memory heap:
This is where memory allocation takes place.
The code snippet below shows how to allocate memory to the memory heap.
let name = "Emmanuel";
let age = 24;
Now the JavaScript engine will allocate memory to the variable name which has a string value called Emmanuel. Same with the age variable.
Memory Leaks
This refers to the unused memory allocations that still exist in our codebase. When the memory allocation exceeds the threshold of the memory heap, the browser becomes slow and eventually, it stops working.
setInterval(() => {
// reference objects
}, 2000)
// now forget to clear the interval.
// you just created a memory leak!
Call Stack:
This is where the code is read and executed. It tells us where we are in our program (call site). It is a very important part when it comes to handle the JavaScript “this binding”.
The code snippet below put the Call Stack in action
console.log("First");
console.log("Second");
console.log("Third");
console.log("Fourth");
// Output
First
Second
Third
Fourth
As we can see, the output of the code snippet above tells us that JavaScript code is executed line by line.
Initially, the Call Stack is usually empty.
The first statement is read and pushed into the Call Stack for execution and after execution, it is popped out of the Call Stack.
Same with the remaining statements.
That was pretty easy right?Let’s try out a somewhat advance Call Stack operation.
let first = () = {
let second = () = {
console.log("welcome")
}
second();
}
first();
In the code snippet above, the first function call is added to the call stack, the Call Stack runs the first function call, inside the first function, it runs the second function call and inside the second function, it runs the console.log
statement.
Finally, the Call Stack sees nothing to execute so it removes all the calls one after the other beginning with the console.log
statement followed by the second function call and the first function call.
Finally the Call Stack is empty again. This is known as the first in, last out principle of the Call Stack.
JavaScript is a single threaded and non blocking language
What does this phrase mean?
Single-threaded means that JavaScript has one Call Stack and its codes can be executed line by line.
Similarly, multi-threaded means more than one Call Stack.
Having one Call Stack makes JavaScript code execution easy since there is no need to address complicated issues such as deadlocks that arise in multi-threaded languages.
The synchronous concept in JavaScript
This means that when code is executed line by line, the preceding line of code blocks the next operation until its execution is completed. Blocking operations may not always seem like an issue because microprocessors in computers are fast.
Imagine the execution of the code snippet below
console.log("Emmanuel");
let result = query('SELECT * from db')
console.log("Next");
while the first console.log
statement is executed quickly, querying the database to select all its data will take a pretty long time making the last console.log
statement wait until it is done executing.
Let’s consider a more visually intuitive illustration.
console.log("Start");
alert("welcome");
input(name);
console.log("Next");
Although synchronous concept in JavaScript is predictable,Ideally, we don’t wait for processes that take a lot of time.
So what is the remedy for such a scenario? Well!! Asynchronous JavaScript to the rescue.
The asynchronous concept in JavaScript
Let’s think of asynchronous as sending a message to your boss. After sending a message to your boss, it may take some time for him to reply to the text.
Within this interval, you can perform other functions with your phone ( maybe go through individual text messages, play games, set alarm and so on) till you get a reply from him.
The setTimeout function
Syntax
setTimeout(callbackFunction, time)
The setTimeout
function come within the browser and it allows us to set the time for an event to occur or a function to be executed. It is part of the web APIs.
console.log("First")
setTimeout(() => {
console.log("Second")
}, 2000)
console.log("Third")
Running this code snippet on your console, you will notice that first is logged to the console followed by third and finally Second is logged to the console two seconds later.
This is the simplest form of handling asynchronous task in JavaScript, but you must avoid this in your code as there are side effects associated with this.
In this code snippet, we told the setTimeout
function to wait for two seconds before executing its callback function.
Within the waiting period, every other piece of code will be executed without being blocked by the setTimeout
function.
This is the basis of asynchronous programming in JavaScript.
JavaScript Runtime Environment
In order for JavaScript to run, we need more than just the JavaScript engine. We need the JavaScript Runtime Environment.It is made up of the following:
- JavaScript engine
- Web APIs
- Callback Queue
- Event Loop
Let’s use the above code snippet to understand the interaction between the web APIs, callback queue and event loop.
Firstly, console.log("First")
goes into the Call Stack and ‘first’ is logged onto the browser’s console. Next, the setTimeout
function goes into the Call Stack. Since setTimeout
is part of the web APIs, the web API will get triggered with a notification that setTimeout
has just been called after which the setTimeout function is popped out of the Call Stack.
The web API starts a timer of 2 seconds. Because the call stack is empty, the JavaScript engine adds console.log("Third")
to the Call Stack and executes it. After 2 seconds, the web API executes the setTimeout
function and adds its callback function to the callback queue.
The event loop keeps checking if the Call Stack is empty and if the Call Stack is empty, the event loop will check if there is any callback function in the callback queue the event loop will move it into the Call Stack for execution and we will have console.log("Second")
logged onto the browser’s console. Finally, the Call Stack is empty again.
Let’s run this piece of code in the console
console.log("First")
setTimeout(() => {
console.log("Second")
}, 0)
console.log("Third")
Did you notice that the result is still the same as the previous code snippet even when the time for the callback function execution is set to zero seconds?
Even though the setTimeout function is set to zero seconds, this code snippet still went through the process. During the process cycle, the Call Stack had already moved to Console.log("Third")
before the setTimeout
function is executed.
N/B the setTimeout
function is not a JavaScript function rather it is part of the web API offered by the browser for asynchronous programming.
Conclusion
Fortunately, the concepts explained in this article constitute some of the frequently asked questions in JavaScript job interviews and as a JavaScript developer preparing for an interview, you are expected to have a sound knowledge of some of these concepts.