What is Asynchronous JavaScript?
JavaScript is a synchronous single-threaded language by default. but asynchronous behavior is achieved
This guide walks you through callbacks, Promises, and async/await with clean, copyable examples. By the end, you'll understand the event loop and write production‑ready async code.
1. Callbacks — the foundation
Callbacks are functions passed as arguments to be executed later. They work well for simple tasks but can lead to "callback hell".
callback.js
console.log("🔵 Start");
setTimeout(() => {
console.log("🟢 Inside callback (after 2 seconds)");
}, 2000);
console.log("🔴 End");
// Output order: Start → End → Inside callback
2. Promises — chainable future values
Promises represent an eventual completion (or failure). They avoid nesting and improve readability.
promise.js
const fetchData = new Promise((resolve, reject) => {
setTimeout(() => resolve("📦 Data loaded"), 1500);
});
fetchData
.then(result => console.log(result))
.catch(err => console.error(err));
// Output after 1.5s: 📦 Data loaded
3. Async/Await — the modern standard
async functions return a Promise, and await pauses execution until resolution — synchronous feel, async behaviour.
async-await.js
async function getUser() {
try {
const res = await fetch('https://jsonplaceholder.typicode.com/users/1');
const user = await res.json();
console.log(`✅ ${user.name}`);
} catch (err) {
console.error("Fetch failed", err);
}
}
getUser();
⚡ Understanding the event loop
🧠 Key insight: Microtasks (Promises) run before macrotasks (setTimeout). The event loop prioritizes microtask queue.
event-loop.js
console.log("1️⃣️ Start");
setTimeout(() => console.log("2️⃣️ Timeout"), 0);
Promise.resolve().then(() => console.log("3️⃣️ Promise"));
console.log("4️⃣️ End");
// Output: 1️⃣️ Start → 4️⃣️ End → 3️⃣️ Promise → 2️⃣️ Timeout
🧰 When to use each pattern
- Callbacks: Simple event handlers, Node.js legacy APIs.
- Promises: Concurrent requests (
Promise.all), chaining async operations. - Async/Await: Sequential logic, clean error handling, modern codebases.
concurrent-fetch.js
async function fetchAllUsers() {
const ids = [1,2,3];
const promises = ids.map(id => fetch(`https://jsonplaceholder.typicode.com/users/${id}`).then(r => r.json()));
const users = await Promise.all(promises);
console.log(users.map(u => u.name));
}
fetchAllUsers();