7/6/2025 · Portfolio Admin

Top 5 Mistakes Developers Make with async/await (And How to Avoid Them)

Synced from Medium RSS

Async/await is a game changer for writing clean asynchronous code in JavaScript. But even experienced developers can trip up! Let’s break down the most common mistakes — and how to avoid them — with simple examples you can use right away.
A modern, 2D digital cover image with a dark background, code snippets, and async/await symbols, visually representing JavaScript asynchronous programming for developers.
Avoiding Common async/await Mistakes in JavaScript — Write cleaner, bug-free asynchronous code!

1. Forgetting to Use await (Or Missing an async Function)

The Mistake:

Calling an async function, but forgetting to use await — or forgetting to mark your function as async.

function fetchData() {
return new Promise(res => setTimeout(() => res('done!'), 1000));
}

function main() {
const result = fetchData(); // Oops! Not awaited
console.log(result); // Prints: Promise {<pending>}
}

How to Fix:

async function main() {
const result = await fetchData(); // Now it works!
console.log(result); // Prints: 'done!'
}
main();

Tip:

Remember: You can only use await inside an async function.

2. Not Handling Errors with try/catch

The Mistake:

Assuming errors will be handled automatically — but async/await code needs try/catch for error handling.

async function getUser() {
throw new Error('User not found!');
}
async function main() {
const user = await getUser(); // Will crash if rejected
}
main();

How to Fix:

async function main() {
try {
const user = await getUser();
} catch (err) {
console.error('Something went wrong:', err.message);
}
}

Tip:

Always wrap your await code with try/catch to avoid app crashes.

3. Running await in a Loop (Serial Instead of Parallel)

The Mistake:

Using await inside a loop, causing each operation to wait for the previous one. This is often much slower.

const urls = [/* 10 URLs */];
for (const url of urls) {
await fetch(url); // Each request waits for the last!
}

How to Fix (Run in Parallel):

const results = await Promise.all(urls.map(url => fetch(url)));

Tip:

Use Promise.all for independent async tasks you want to run together.

4. Ignoring Returned Promises (Uncaught Async Code)

The Mistake:

Not returning or handling promises inside functions, so async errors go unhandled.

app.get('/user', async (req, res) => {
getUser(); // Not awaited or returned!
res.send('ok');
});

How to Fix:

app.get('/user', async (req, res) => {
await getUser(); // Ensures errors bubble up
res.send('ok');
});

Tip:

Always return or await promises in async routes or functions, especially in frameworks like Express.

5. Mixing .then() and await (Messy Code)

The Mistake:

Mixing await with .then() in the same codebase, which makes it hard to read and maintain.

async function foo() {
await fetch('url')
.then(res => res.json())
.then(data => console.log(data));
}

How to Fix:

async function foo() {
const res = await fetch('url');
const data = await res.json();
console.log(data);
}

Tip:

Stick to one style — async/await — for readability and clarity.

Final Thoughts

Async/await makes asynchronous JavaScript feel almost synchronous — but only if you use it wisely. Keep your code clean, handle errors, and be mindful of how you run parallel operations.
Master these basics, and your async code will be bug-free and easy to read!