Skip to content

Async Programming Basics

JavaScript is single-threaded, but most real work (network requests, timers, file I/O) is asynchronous β€” it happens in the background without blocking the rest of the program. JavaScript has evolved three ways to handle async results: callbacks (oldest), Promises (an object representing a future value), and async/await (syntax sugar over Promises that reads like synchronous code).

// Callback style (older)
setTimeout(() => console.log("1 second later"), 1000);
// Promise style
fetch("/api/user")
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
// async/await style (modern, most readable)
async function getUser() {
try {
const response = await fetch("/api/user");
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}

Forgetting await when calling an async function β€” you get the Promise object itself instead of the resolved value, since an async function always returns a Promise.

async function getUser() {
return { name: "Alice" };
}
const user = getUser();
console.log(user.name); // undefined -- `user` is a Promise, not the object!
const user = await getUser(); // must be inside an async function
console.log(user.name); // "Alice" -- correct
  1. What does an async function always return?

    AnswerA Promise β€” even if you write a plain return value;, JavaScript wraps it in a resolved Promise automatically.
  2. What happens if you forget await before an async function call?

    AnswerYou get the pending Promise object itself instead of the resolved value β€” you have to await it or chain .then() to get the actual result.
  3. How do you handle errors in async/await code?

    AnswerWrap the await calls in a try/catch block, same as synchronous error handling.