technology, computer, code-1283624.jpg

Working with Asynchronous Javascript

In this blog, we will be talking about how this synchronous programming language, performs asynchronous non-blocking code.

How is Javascript executed?

Well, JavaScript is synchronous by default and follows a single-threaded Model. This means that code cannot create new threads and run in parallel. In comparison, computers are asynchronous by nature.

Most code is synchronous, where it’s executed line by line; each line of code waits for the previous line to finish. Long-running operations block code execution, for example, downloading a large file with a poor connection.

Blocking operations would adversely affect the performance of our code, so a solution to this is Asynchronous code. Asynchronous code is non-blocking, this implies that Javascript will execute the rest of the code while waiting for an operation to complete.

There are 3 main aspects of Asynchronous Javascript, each was created to solve a problem that a previous implementation had.

Evolution of Javascript:

ES2015 → Callbacks to Promises

ES2017 → Implementation of Async and await


In JavaScript, a callback is a function passed into another function as an argument to be executed later.

The problem: Callbacks do not work well at scale as the complexity of the tasks grow.

This usually results in nesting callback functions otherwise known as callback hell, deep nesting goes against common coding practices. 

The solution: Promises ✅ 

This deep nesting led to the need for promises. Promises are a container for an asynchronously delivered value/container for a future value e.g., a response from an AJAX call. We don’t get a response initially, but we know we’ll get one in the future. Once we get a response these promises are used/consumed or handled for errors.

Javascript promises can exist in 3 possible states (Pending, Fulfilled, and Rejected).
“Pending” implies the operation is neither fulfilled nor rejected, “Fulfilled” indicates the operation was successful and “Rejected” implies that the operation failed.

Promises allow us to no longer rely on events and callbacks passed into asynchronous functions to handle asynchronous results.

Instead of nesting callbacks, we can chain promises for a sequence of asynchronous operations: hence escaping callback hell. This solution however does not come without its own challenges. Chaining promises introduces syntax complexity.

The solution: The async function and the await Keyword ✅

Async and await are built on promises. The purpose of async/await is to reduce the complexity of the syntax e.g., reducing the boilerplate around promises, and the “don’t break the chain” limitation of chaining promises.

Through async and await we can make the code look like it’s synchronous, but it’s asynchronous and non-blocking behind the scenes.

A quick overview of how asynchronous code is executed behind the scenes in the browser:

The two most important aspects are the call stack Queue and the event loop:

The call Stack: Has a LIFO (Last in, First out) queue data structure, which is used to store all the execution context (order of execution) created during the code execution. The Javascript code gets pushed and executed one by one as the interpreter reads your program and gets popped out once the execution is done. The call-stack is used for synchronous functions.

Asynchronous Functions are handled by the Micro-tasks Queue (Similar to Call stack). This queue specifically handles promises. It’s important to realise it has priority over the call stack queue.

Then Event Loop keeps running continuously and checks the Main stack, if it has any frames to execute, if not then it checks the Callback queue, if Callback queue has codes to execute then it pops the message from it to the Main Stack for the execution.

Callback Queue: This is where your asynchronous code gets pushed to, and waits for the execution.

Heap: This is where all the memory allocation happens for the variables, that you have defined in your program.

Web API: Handles AJAX and JSON requests.

‘Kash works as a full-stack software developer at WayMaker Digital, helping clients to solve business and technology challenges.

WayMaker Digital provides technology consulting, product design and information products, that enable our clients to consistently thrive and innovate to meet user needs. The quality of our experiences and ideas set us apart when it comes to service delivery, customer experience design and product development. 

Our team of consultants have built digital experiences for leading brands with complex business scenarios ranging from startup companies to public services and from telecoms to e-commerce; no project deliverable is too complex.

Our approach: we adopt human-centred & design thinking models to solve complex business challenges, which ensure our clients are on top of their business.

Do you have a question or an enquiry; you want to discuss a project or need a free consultation? Give us a shout here.

Share with Friends

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top