Mohith Kankanala

Mohith Kankanala

What exactly is Async/Await?

Dec 21, 2025

When you use async keyword in JavaScript, you are defining a function that will return a promise. Even if you don't explicitly return a promise, it wraps your return value in one.

async function getNumber() {
return 42;  // Actually returns Promise.resolve(42)
}

What is a promise?

A promise is an object that gets returned immediately but the value it contains will be available later on depending on the result of the asynchronous operation.

Here's a example with the Fetch API:

// Without await - you get a Promise
const promise = fetch('https://api.example.com/user/1');
console.log(promise);  // Promise { <pending> }
 
// With await - you get the actual response
const response = await fetch('https://api.example.com/user/1');
console.log(response);  // Response { status: 200, ... }

You can also create promises manually using the Promise constructor:

const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello, world!');
    }, 1000);
});

In the above example, the promise will be resolved with the value 'Hello, world!' after 1 second.

What is resolve?

resolve is a function that is called when the asynchronous operation is successful.

resolve('Hello, world!');

What is reject?

reject is a function that is called when the asynchronous operation fails.

reject(new Error('Failed to fetch data'));

What is setTimeout?

setTimeout is a function that is used to delay the execution of a function.

setTimeout(() => {
resolve('Hello, world!');
}, 1000);

The Mental Model

Think that you are getting a box from the store, but what's inside the box is not known yet. You can only open the box after 1 second. While you are waiting, you can do other things like watching a movie or reading a book. That is what await does. It allows the thread to continue executing other code while waiting for the promise to be resolved.

Here's the key thing:

Even when you await opening the box, the store doesn't close. Other customers can still be served, other boxes can be prepared. The JavaScript engine keeps running and handling other tasks.

The point

Do not block the main thread for database queries or API calls. Makes the website more responsive and be able to handle more requests.

Question

Do we want to await for the promise to be resolved or not?

The answer depends on if we want to use the result of the promise in the next line of code or later on.

If we want to use the result in the next line of code, we await for the promise to be resolved:

const result = await fetchData();
console.log(result);  // Actual data

If the answer is no, then the code will continue to execute without awaiting for the promise to be resolved:

const result = fetchData();
console.log(result);  // Promise { <pending> }

The result will be a Promise object because the promise is not resolved yet.

What await actually does

Here's what I got confused about initially. Whether you use await or not, the asynchronous operation itself never blocks the main thread. The difference is in how your function handles it.

// WITHOUT await - doesn't block
const promise = fetchData();
console.log("This runs immediately");  // Runs right away
// promise is still pending in background
 
// WITH await - ALSO doesn't block the main thread
const result = await fetchData();
console.log(result);  // Waits for result, but engine can still handle other events

Think of it like this:

The main thread can still process:

Running operations in parallel vs sequential

This is where understanding await becomes really useful. If you have multiple async operations that don't depend on each other, you don't want to wait for each one before starting the next.

// Sequential (slower) - waits for each one
const user = await fetchUser();
const posts = await fetchPosts();  // Waits for user to finish first
// Total time: time(fetchUser) + time(fetchPosts)
 
// Parallel (faster) - both start immediately
const [user, posts] = await Promise.all([
  fetchUser(),
  fetchPosts()
]);
// Total time: max(time(fetchUser), time(fetchPosts))

In the parallel version, both fetch operations start at the same time. We only await once for both of them to complete.

Summary

Will cover the event loop in the next post......