JS Asynchronous
JavaScript runs one thing at a time on the main thread. To stay responsive, slow work (network requests, timers, file reads) happens asynchronously — JavaScript hands it off and gets a callback when it's done.
The four async patterns, in order
| Pattern | Shape | Status |
|---|---|---|
| Callbacks | doThing(arg, cb) | Original mechanism. Leads to "callback hell" when nested. |
| Promises | doThing().then(…).catch(…) | Chained, composable. Modern APIs return them. |
| async / await | const x = await doThing() | Promises with synchronous-looking syntax. Today's default. |
| Generators / iterators | function*(){ yield … } | Niche — pausing computation, custom iteration. |
Promise basics
JS
fetch("/api/user")
.then(res => res.json())
.then(user => console.log(user))
.catch(err => console.error("Failed:", err));
async / await
JS
async function loadUser() {
try {
const res = await fetch("/api/user");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const user = await res.json();
return user;
} catch (err) {
console.error("Failed:", err);
}
}
Running things in parallel
JS
// Wait for all — fails fast if any reject
const [a, b, c] = await Promise.all([
fetch("/a").then(r => r.json()),
fetch("/b").then(r => r.json()),
fetch("/c").then(r => r.json()),
]);
// First one to finish (or reject)
const winner = await Promise.race([fast(), backup()]);
// Wait for all, capture each outcome (never rejects)
const settled = await Promise.allSettled([api1(), api2(), api3()]);
The event loop in one paragraph
JavaScript runs synchronous code first. Asynchronous results (timers, network, etc.) wait in a queue. When the call stack is empty, the loop pulls the next queued job and runs it. That's why setTimeout(fn, 0) doesn't run immediately — it waits for the current code to finish first.
Tip: Default to
async/await for readability. Reach for Promise.all when you have independent work that can run in parallel — sequential awaits are the most common performance mistake in JS.Example
Example
<!DOCTYPE html>
<html>
<body>
<p id="out"></p>
<script>
document.getElementById("out").textContent = "Hello from JS Asynchronous!";
</script>
</body>
</html>
Try it Yourself »
Exercise
Wait for a fetch to resolve inside an async function.
const res =
fetch('/api');
Pauses execution until the promise settles.
Discussion
Loading…