DEV Community

Cover image for Async/Await Easiest Explanation For Beginners
Shubh Sharma
Shubh Sharma

Posted on

Async/Await Easiest Explanation For Beginners

Intro

Before learning about async/await you should know what and how promises work in JavaScript. You can read about promises here

What is async/await?

async/await were introduced in 2017, Before that managing asynchronous operations in javaScript was primarily done using promises.

While promises helped in the "callback hell" issue, they still introduced a certain level of complexity, especially when dealing with multiple async operations in sequence.

Async/await was introduced to make working with asynchronous code even more easy and readable. It provides a syntax that looks and behaves like synchronous code.

It is still built on top of Promises and is compatible with all existing Promise-based APIs.

Creating an async function using async keyword πŸ‘‡

async function functionName() {}
Enter fullscreen mode Exit fullscreen mode

async function working

An async function created with async keyword will always return a promise.

There could be 2 situations:

  • You return a promise explicitely like this
// explicitely returning the promise
async function functionName() {
  return new Promise((resolve, reject) => {
     resolve("Some data")
  })
}
Enter fullscreen mode Exit fullscreen mode
  • You return any other value like number, object, string, array, etc, but here the JavaScript engine wraps that value inside a promise object to ensure that the value returned is a promise.

You will find second case in more professional code some examples such as fetch() or promisified version of fs methods or other promisified methods.

async function asyncFunction2() {
    // this gets wrapped inside a promise object
    return "String";
}
Enter fullscreen mode Exit fullscreen mode

What about the await keyword?

The await keyword is used inside an async function to pause the function execution until a promise settles.

To understand this first understand how callstack and basic functions work πŸ‘‡

JavaScript thread works by pushing the variables and function calls inside callstack. This function is not popped out of the stack until the code inside the function is completed executing.

But when its an async function with await keyword used inside, the story is different.

When JavaScript thread sees the await keyword inside the async function, the function is suspended from the callstack, meaning it is popped out until the promise is completed (resolved or rejected) and once promise is finished the function is again pushed on the stack and it continues from where it left off with the result of the promise.

This is where a lot of beginners get confused. So a point to note here is:

Point: Await keyword will only suspend the parent async function in which it is written. This means that JS thread is not blocked and can continue the other work out of the function.

Code example and Explanation

function returnData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('Promise is resolved');
    }, 3000);
  });
}

async function fetchDataWithAwait() {
  const data = await promisificaction("Promise");
  console.log(data);
  console.log("Thread waited because of await keyword!")
}

fetchDataWithAwait();

console.log("Thread is still free to work!");
Enter fullscreen mode Exit fullscreen mode

Explanation of code:

  1. JS thread sees the returnData function which returns a resolved value after 3 seconds (setTimeout function is making sure of 3 seconds delay)

  2. JS thread sees the fetchDataWithAwait function declaration.

  3. JS thread now sees the fetchDataWithAwait() call and pushes the function on the callstack.

  4. JS thread finds the await keyword and suspends this function from the callstack until promise is resolved (3 seconds)

  5. JS thread continues to next line and prints "Thread is still free to work!" on the console

  6. Now since the JS thread is idle, it pushes the async function back to the callstack and starts execution from where it left off.

  7. "Promise is resolved" is printed on the console.

  8. "Thread waited because of await keyword!" is now printed.

Output:

output for the code

Why use aync/await when we already had promises?

Because the syntax of promises is confusing while await makes it more clear and readable.

Promises create a lot of confusion when you are dealing with API calls again and again in your code.

async/await fixes that confusion.

Remember that async/await still uses promises behind the scenes but it just makes the syntax more readable.

Using try/catch() to handle errors

Since async/await does not handle errors by default so we wrap them inside a try and catch() block of code.

try() is used to try the piece of code we wrote and catch() catches any error thrown by the api calls like in this example. This ensures the proper error handling.

 async function fetchDataWithAwait() {
  try {
    const data = await promisificaction("Promise");
    console.log(data);
    console.log("Thread waited because of await keyword!")
  } catch (error) {
    console.log(error);
  }
}

fetchDataWithAwait();
Enter fullscreen mode Exit fullscreen mode

Conclusion

Once you know how to use async/await Async js becomes really easy. Took me many days to properly grasp all this but I tried to put this in easiest way possible.

After all it is said that if you can not explain something in easy terms then you don't know it properly. ;)

Top comments (0)