Async/await is the latest format for writing asynchronous code. If you are a Node JS programmer, you probably have heard a lot about async/await. It is built over promises for simplifying the code structure and also to make and behave more like the synchronous code.

If you are familiar with the concept of promises or callbacks, you should know that they deliver the same value. By using callbacks, promises or async/await in your code, you ensure your code to be non-blocking. This means that if any part of our code is going to take some time to respond (for eg. database calls or file reads), the main thread can run some other code/functions in the meantime. So, the concept is the same for all three of them but the way of writing code is different. Basically, they are different forms of syntaxes.

In this article, I have taken a shot to explain the concept of async/await with a real-life analogy.

Suppose, a chef has to prepare pasta and rice pudding for the dinner. In this scenario, imagine the stove to be the main thread. It has two processes to finish which are completely independent of each other:

  1. Prepare pasta (function 1)
  2. Prepare rice pudding (function 2)

The chef starts to prepare pasta on the stove but realized that he ran out of the Olive oil and without that he can not start cooking pasta. He called his assistant Tim to go to the supermart and get some oil.

async call

Tim agreed to get some oil from supermart but this process will take some time.

io call

As Tim is gone for oil, the chef has to wait to get started to pasta.


Hmm, so the stove (our main thread) is empty and can prepare something else in the meantime. So, the chef started on rice pudding while waiting for olive oil as:

  1. Rice pudding does not need olive oil (independent function)
  2. The stove is empty (main thread is empty and can perform other tasks because of non-blocking property)

thread use

Now, there are two scenarios:

Tim happily came back with oil - This will trigger the success callback and the chef will start preparing pasta once he is done with pudding.

success callback

Tim did not find oil and came back to inform - This will trigger error callback and chef is informed that oil is not available.

failure callback

The syntax for async/await -

const pasta = async () => {
  await get_oil();
  return make_pasta();
const pudding = async () => {
  return make_pudding();

const dinner = async () => {
   pasta = pasta()
   pudding = pudding()

Now, dinner is a function which does not wait for pasta to be made before starting making pudding.

We could have also made a synchronous dinner which waits for pasta to be done before starting pudding

const dinner = async () => {
   pasta = await pasta()
   pudding = await pudding()

However, this would not have been a good use of our resources because while making pasta, when we are getting oil, we are not utilising the main thread.

Hope this example helps you understand how async/await is similar to callbacks, yet different.