Asynchronous JavaScript: Promises and async/await
Some operations — fetching data from a server, reading a file — take time to complete. Unlike a normal function call, JavaScript doesn’t pause and wait for these; it hands you a Promise, an object representing a value that will exist eventually, and moves on to run other code in the meantime.
fetch("https://api.example.com/courses")
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
Each .then() runs once the previous step resolves successfully, and receives whatever value that step returned. .catch() runs if anything in the chain fails — a network error, a bad status code you check yourself, or an exception thrown inside any .then().
async/await — the cleaner syntax
async function loadCourses() {
try {
const response = await fetch("https://api.example.com/courses");
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
await can only be used inside a function marked async. It makes asynchronous code read top-to-bottom like normal synchronous code, which is why most modern JavaScript prefers async/await over chaining .then() calls directly — it doesn’t block the whole browser while waiting, it just pauses that specific function until the Promise settles.
Running multiple requests at once
const [courses, internships] = await Promise.all([
fetch("/api/courses").then(r => r.json()),
fetch("/api/internships").then(r => r.json()),
]);
Promise.all runs several async operations in parallel rather than one after another, and waits for all of them to finish. This is significantly faster than await-ing each request individually when they don’t depend on each other’s results.
A common mistake
Forgetting await in front of an async call doesn’t cause an error — it just gives you back the Promise object itself instead of the actual data, which then produces confusing bugs further down your code where you expected a real value. If a variable is unexpectedly showing Promise { <pending> } in the console, you almost certainly forgot an await.