Async/Await Patterns You Should Know

matt
Matthew Gros · Nov 25, 2025

TLDR

Use Promise.all for parallel operations, handle errors with try/catch, avoid mixing callbacks and promises.

Async/Await Patterns You Should Know

From Callbacks to Async/Await

The evolution of JavaScript async code.

Callback Hell

getUser(id, (err, user) => {
    if (err) return handleError(err);
    getOrders(user.id, (err, orders) => {
        if (err) return handleError(err);
        getProducts(orders[0].id, (err, products) => {
            // Deep nesting nightmare
        });
    });
});

Promise Chains

getUser(id)
    .then(user => getOrders(user.id))
    .then(orders => getProducts(orders[0].id))
    .then(products => console.log(products))
    .catch(handleError);

Async/Await

async function loadData(id) {
    try {
        const user = await getUser(id);
        const orders = await getOrders(user.id);
        const products = await getProducts(orders[0].id);
        return products;
    } catch (error) {
        handleError(error);
    }
}

Parallel Execution

// Sequential (slow)
const users = await getUsers();
const posts = await getPosts();
const comments = await getComments();

// Parallel (fast)
const [users, posts, comments] = await Promise.all([
    getUsers(),
    getPosts(),
    getComments()
]);

Promise.allSettled

When you need all results, even failures:

const results = await Promise.allSettled([
    fetch('/api/users'),
    fetch('/api/posts'),
    fetch('/api/comments')
]);

results.forEach(result => {
    if (result.status === 'fulfilled') {
        console.log(result.value);
    } else {
        console.log('Failed:', result.reason);
    }
});

Racing Promises

First one wins:

const result = await Promise.race([
    fetch('/api/data'),
    timeout(5000)  // Reject after 5s
]);

Common Mistakes

// Forgetting await
const user = getUser(id);  // user is a Promise, not data

// Await in loops (sequential when parallel is possible)
for (const id of ids) {
    await processItem(id);  // Slow
}

// Better
await Promise.all(ids.map(id => processItem(id)));  // Parallel

About the Author

matt

I build and ship automation-driven products using Laravel and modern frontend stacks (Vue/React), with a focus on scalability, measurable outcomes, and tight user experience. I’m based in Toronto, have 13+ years in PHP, and I also hold a pilot’s license. I enjoy working on new tech projects and generally exploring new technology.