Looking for a structured path? Browse all JavaScript lessons.
- Maintained by
- Learning Platform content team
- Reviewed by
- Learning Platform source and executable-example contract
JavaScript async/await errors: four reliable fixes
Async bugs often look unrelated: [object Promise], Promise { <pending> }, an unhandled rejection, or an array of promises instead of values. They share one cause: code lost track of when a promise settles.
1. Await the value before using it
async function loadName() {
return "Ada";
}
async function main() {
const name = await loadName();
console.log(`Hello, ${name}`);
}
main();
Expected output: Hello, Ada. Without await, name is a Promise, not a string.
2. Catch at the boundary that can recover
async function readConfig() {
throw new Error("config unavailable");
}
async function main() {
try {
await readConfig();
} catch (error) {
console.log("Using defaults");
}
}
main();
Expected output: Using defaults. A try block without await does not catch a later rejection if the promise escapes it.
3. Use Promise.all for independent work
const wait = (value) => Promise.resolve(value * 2);
async function main() {
const values = await Promise.all([wait(2), wait(3)]);
console.log(values); // [4, 6]
}
main();
Sequential await is correct when each operation depends on the previous result. For independent operations it adds avoidable latency.
4. Do not expect map(async …) to unwrap itself
items.map(async item => ...) returns Promise[]. Wrap it in await Promise.all(...). Conversely, forEach(async ...) does not wait at all; use for...of for deliberate serial work.
Failure mode
Adding .catch(() => {}) removes the warning and the evidence. Handle the error with a fallback, rethrow it with context, or let a top-level boundary report it.
Run these snippets in the JavaScript playground, then continue with Async and Promises and Error Handling.