JavaScript : Synchronous vs Asynchronous
Synchronous means one after another. In synchronous programming we execute the code line by line. This also means we wait for the particular line of code to get executed completely before we move on to the next line of code. Suppose we make a request to a server, and that request is taking 30 seconds to be processed. So during these 30 seconds we would stay idle. This isn't good, neither for homo sapiens nor for JavaScript.
JavaScript is single threaded, it can only perform one task at a time. Here we introduce asynchronous programming. In this we offload long running tasks to the background thread. JavaScript manages asynchronous tasks with the help of an Event Loop.
Asynchronous code can be written in 3 ways :
Callbacks
Promises
async
andawait
The Event Loop
While execution, every function which is called is added to the JavaScript call stack.
Each entry in the stack is called a
stack frame
. A stack frame contains the information of the function call such as arguments, locals of the function, return address and others.Quite evidently, call stack follows the LIFO principle.
If JavaScript encounters a function functionA() being called, it is added to the call stack. If that function functionA() calls another function functionB(), then functionB() is added to the top of the call stack. As JavaScript completes the execution of a function, it is removed from the call stack. Therefore, JavaScript will execute functionB() first, remove it from the stack when complete, and then finish the execution of functionA() and remove it from the call stack. This is why inner functions are always executed before their outer functions.
When JavaScript encounters an asynchronous function, it adds it to a table in its memory (heap). And the function gets executed by the Web API call. This table stores:
The operation
The condition for it to be completed
And the function to be executed once its completed
When this operation completes, JavaScript adds the associated function to the
message queue
or thecallback queue
.Functions in the message queue wait to be added to the call stack.
The
event loop
is a perpetual process that checks if the call stack is empty.If the call stack is empty, the first item from the
message queue
is added to thecall stack
.
The event loop and the callback queue are not part of the JavaScript engine, rather they sit outside JavaScript engine and normally provided by the runtime such as a web browser or NodeJs.
Callbacks - A callback function is passed as an argument to another function, and is executed when the other function is finished executing. Callbacks ensure that some part of the code is being executed only after the asynchronous task is done executing. It's common for JavaScript developers to use anonymous
functions as callbacks. Anonymous
means nameless functions.
Suppose we request an API for some data. And we are using callbacks. We will have a callback function to receive that data. Then there is another nested callback for pushing this data onto a database. And so. This is called callback hell
. Code gets unmanageable and clumsy.
Promises - A promise is a JavaScript object that will return a value at some point in the future. If we get a value in the future, we say the promise is fulfilled otherwise it is rejected. Promises also use callback functions. We have a callback function for the then()
method which is executed if the promise is fulfilled. And we have a callback for the catch()
method to handle errors.
A promise can return a promise allowing us to execute promises one after the other. This is called promise chaining.
Async
and Await
- We define a function with the async
keyword to tell JavaScript that this is an asynchronous function and it would return promises. We use the await
keyword to tell JavaScript to return the results of the promise instead of returning the promise itself when it's fulfilled.
Here, we use try-catch
for error handling.
Last updated