DG
DevGuide
Run Code
Home/JavaScript/Async JavaScript
JS JavaScript7 / 7

Async JavaScript

📌 WHAT

Asynchronous code allows operations (API calls, file reads, timers) to run without blocking the rest of the program. JavaScript is single-threaded, so async patterns are critical.

💡 WHY

Without async, a single network request would freeze your entire UI for seconds. Async lets your app stay responsive while waiting for slow operations.

⏰ WHEN / WHERE

Every API call, database query, file operation, timer, or any operation that takes time. In React + Next.js this is used constantly.

🔧 HOW

Use async/await syntax. Mark a function with async, then await any Promise-returning call. Wrap in try/catch for error handling.

📚Key Terms

Promise

— An object representing a future value. Has three states: pending, fulfilled, rejected

async function

— A function that automatically returns a Promise. Allows use of await inside it

await

— Pauses execution inside an async function until a Promise resolves. Like 'wait for this to finish'

Event Loop

— JavaScript's mechanism for handling async operations. The call stack, web APIs, and callback queue work together

Code Examples

#1Promises → async/await (modern way)

Promises → async/await (modern way)
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// OLD WAY: Promise chains (callback hell)
fetch("https://jsonplaceholder.typicode.com/users/1")
.then(response => response.json())
.then(user => {
console.log(user);
return fetch(`/api/posts?userId=${user.id}`);
})
.then(response => response.json())
.then(posts => console.log(posts))
.catch(error => console.error(error)); // one catch for all
// ✅ MODERN WAY: async/await — reads like synchronous code
async function fetchUserAndPosts(userId) {
try {
// await pauses here until response comes back
const userResponse = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
if (!userResponse.ok) {
throw new Error(`HTTP error! status: ${userResponse.status}`);
}
const user = await userResponse.json(); // await again for parsing
console.log("User:", user);
const postsResponse = await fetch(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`);
const posts = await postsResponse.json();
console.log("Posts:", posts);
return { user, posts };
} catch (error) {
console.error("Something went wrong:", error.message);
throw error; // re-throw so caller can handle it
}
}
// Call async function
fetchUserAndPosts(1);

#2Parallel async with Promise.all

Parallel async with Promise.all
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Running multiple async operations in PARALLEL
async function fetchDashboardData(userId) {
try {
// ❌ Sequential — slow! Each waits for previous
// const user = await getUser(userId);
// const posts = await getPosts(userId);
// const comments = await getComments(userId);
// ✅ Parallel — all 3 start at the same time!
const [user, posts, comments] = await Promise.all([
fetch(`https://jsonplaceholder.typicode.com/users/${userId}`).then(r => r.json()),
fetch(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`).then(r => r.json()),
fetch(`https://jsonplaceholder.typicode.com/comments?postId=1`).then(r => r.json()),
]);
// All three are done by this line
return { user, posts, comments };
} catch (error) {
// Promise.all rejects if ANY promise fails
console.error(error);
}
}
// Promise.allSettled — doesn't fail if one rejects
const results = await Promise.allSettled([
fetch('/api/users').then(r => r.json()),
fetch('/api/broken-endpoint').then(r => r.json()),
]);
// results[0] = { status: 'fulfilled', value: [...] }
// results[1] = { status: 'rejected', reason: Error }

Practice This Concept

Open the playground, paste any example, and experiment. The best way to learn is by breaking things.

Open in Playground