Async JavaScript: Promises & async/await
Network requests, timers and file access are asynchronous. Understand the event loop, Promises and async/await to write non-blocking code without callback hell.
The Event Loop in One Minute
JavaScript runs on a single thread. Long operations such as network calls are handed to the environment, and their callbacks are queued to run when the call stack is empty. This keeps the page responsive instead of freezing while waiting.
Promises
A Promise represents a value that will exist in the future. It is either pending, fulfilled or rejected. You chain results with `.then()` and handle errors with `.catch()`.
const wait = (ms) =>
new Promise((resolve) => setTimeout(resolve, ms));
wait(500)
.then(() => fetch("https://api.github.com/users/octocat"))
.then((res) => res.json())
.then((user) => console.log(user.login))
.catch((err) => console.error("Failed:", err))
.finally(() => console.log("done"));async / await
`async/await` is syntax built on Promises that reads like synchronous code. Always wrap awaited calls in `try/catch`, and remember that `fetch` does not reject on HTTP error statuses, so check `res.ok`.
async function getUser(username) {
try {
const res = await fetch(`https://api.github.com/users/${username}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (error) {
console.error("Could not load user:", error.message);
return null;
}
}
const user = await getUser("octocat");
console.log(user?.public_repos);Running Tasks in Parallel
Awaiting calls one after another is slow when they are independent. Start them together with `Promise.all` (fail fast) or `Promise.allSettled` (collect every result):
const users = ["octocat", "torvalds", "gaearon"];
const results = await Promise.allSettled(
users.map((u) => fetch(`https://api.github.com/users/${u}`).then((r) => r.json()))
);
results.forEach((r, i) => {
if (r.status === "fulfilled") console.log(users[i], r.value.followers);
else console.warn(users[i], "failed");
});Key Takeaways
- JavaScript is single-threaded; async work is queued through the event loop.
- Promises model future values; async/await makes them read linearly.
- Always handle errors and check res.ok when using fetch.
- Use Promise.all or allSettled to run independent tasks in parallel.
Contact Us
Have a question or feedback? Fill out the form below or reach us directly at support@nvaitraining.com