«Back to Home

Learn JavaScript

Topics

async and await in JavaScript

You already learned how Promises make asynchronous code easier.
However, writing .then() and .catch() repeatedly can still become long and cumbersome.

That's why JavaScript introduced async/await — a cleaner, simpler way to work with Promises.

Think of async/await as writing asynchronous code that appears synchronous.

What is async?

The async keyword is added before a function to make it return a Promise automatically.

Example:

async function test() {
    return "Hello";
}

test().then(result => console.log(result));

Output:

Hello

Even though you returned a string, JavaScript wraps it inside a Promise.

What Is await?

The await keyword is used inside async functions to wait for a Promise to resolve.

Example:

async function myFunc() {
    let result = await Promise.resolve("Done");
    console.log(result);
}

myFunc();

Output:

Done

The function pauses at await until the Promise finishes.

Example 1: Using await with setTimeout

We simulate a delay using a Promise:

function delay() {
    return new Promise(resolve => {
        setTimeout(() => resolve("Finished waiting"), 2000);
    });
}

async function run() {
    console.log("Start");
    let res = await delay();
    console.log(res);
    console.log("End");
}

run();

Output:

Start
(2 seconds delay)
Finished waiting
End

Example 2: Simulating an API Call

function getData() {
    return new Promise(resolve => {
        setTimeout(() => resolve("User data received"), 1500);
    });
}

async function loadUser() {
    console.log("Loading...");
    let data = await getData();
    console.log(data);
}

loadUser();

Output:

Loading...
User data received

async/await vs then/catch

Using then/catch:

getData()
    .then(res => console.log(res))
    .catch(err => console.log(err));

Using async/await:

async function show() {
    try {
        let res = await getData();
        console.log(res);
    } catch (err) {
        console.log(err);
    }
}

async/await makes code shorter and easier to read.

Error Handling with try…catch

Best practice: always wrap await inside try/catch.

function getUser() {
    return new Promise((resolve, reject) => {
        let success = false;

        setTimeout(() => {
            if (success) resolve("User Loaded");
            else reject("Failed to load user");
        }, 1000);
    });
}

async function load() {
    try {
        let res = await getUser();
        console.log(res);
    } catch (err) {
        console.log("Error:", err);
    }
}

load();

Output:

Error: Failed to load user

Example 3: Multiple Awaits in Sequence

function step1() {
    return Promise.resolve("Step 1 done");
}
function step2() {
    return Promise.resolve("Step 2 done");
}
function step3() {
    return Promise.resolve("Step 3 done");
}

async function runSteps() {
    let s1 = await step1();
    console.log(s1);

    let s2 = await step2();
    console.log(s2);

    let s3 = await step3();
    console.log(s3);
}

runSteps();

Output:

Step 1 done
Step 2 done
Step 3 done

Example 4: Running Promises in Parallel

Using Promise.all with async/await:

function t1() {
    return new Promise(resolve => setTimeout(() => resolve("Task 1"), 1000));
}
function t2() {
    return new Promise(resolve => setTimeout(() => resolve("Task 2"), 1500));
}

async function parallel() {
    let results = await Promise.all([t1(), t2()]);
    console.log(results);
}

parallel();

Output:

["Task 1", "Task 2"]

Example Program (Complete)

function getUser() {
    return new Promise(resolve => {
        setTimeout(() => resolve("User data"), 1000);
    });
}

function getOrders() {
    return new Promise(resolve => {
        setTimeout(() => resolve("Order history"), 1500);
    });
}

async function loadDashboard() {
    console.log("Loading dashboard...");

    let user = await getUser();
    console.log(user);

    let orders = await getOrders();
    console.log(orders);

    console.log("Dashboard ready");
}

loadDashboard();

Output:

Loading dashboard...
User data
Order history
Dashboard ready

Common Mistakes Beginners Make

  1. Trying to use await outside an async function

  2. Forgetting to wrap await code inside try/catch

  3. Running promises in sequence when they can run in parallel

  4. Thinking await blocks the entire program

  5. Misunderstanding async return values

Practice Tasks (Do It Yourself)

  1. Create an async function that waits 1 second and prints a message.

  2. Write a fake login function using async/await.

  3. Use try/catch to handle an error from a rejected promise.

  4. Write two async tasks and run them in parallel using Promise.all.

  5. Chain three awaits that simulate API calls.