Skip to content

JS: Async/Await

Published: September 23, 2024

3 min read


JS: Async/Await

I know, I'm late to the party, but I finally dug into how JavaScript handles async/await under the hood—so here I am.


Everyone knows what async/await does, but here's a quick summary anyway:

async/await is a way to handle async ops in JavaScript. It makes your code look synchronous, saves you from the "callback hell" while handling Promises in the background. Coming from a mobile app background, I'm familiar with how Kotlin Coroutines work and how suspend functions operate internally.

On the surface, they seem pretty similar code-wise:

Kotlin Coroutines

kotlin
suspend fun fetchData() {
    val data = withContext(Dispatchers.IO) {
        // do stuff here
    }
}

JavaScript

js
async function fetchData() {
    const data = await fetchFromApi();
}

In both cases, the function pauses until the async op. is complete, keeping the code simple and readable.

JavaScript Promises

A Promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value.

But how does async/await work with these Promises behind the scenes?

When you mark a function as async and use the await keyword inside, here's what happens:

  1. Checking for Promises:
    When JS encounters the await keyword, it first checks whether the value you're awaiting is a promise. If it's not, the language engine immediately wraps it into an immediately resolved promise.

  2. Non-Blocking Execution:
    If the value is indeed a promise, such as when you use await with the fetch method, JavaScript doesn't block the main thread for other methods in call stack. Instead, it runs the promise in the background.

  3. Call Stack Management:
    JavaScript's event loop and microtask queue come into play. When the await keyword is found, the function is temporarily removed from the call stack, allowing other functions to execute.

  4. Resumption of Execution:
    The function's execution pauses but doesn’t stop entirely. The promise runs in the background, and once it’s fulfilled, the event loop resumes the function from the line following the await keyword.

Darshan Pandya