[React][API] Understand async/await and Build Async Requests
Stop logging Promise pending after fetch - declare async functions, pause with await until data arrives, and replace nested .then chains with readable top-to-bottom code.

1. Environment
- OS: Windows 11 / macOS
- Language: JavaScript (ES8+)
- Frontend library: React.js
- IDE: Visual Studio Code (VS Code)
2. Problem
Suppose you fetch user data from a server and show it on screen.
JavaScript is impatient by nature. It fires fetch, then runs the next line (console.log) without waiting for the response.
You end up with undefined or Promise { <pending> } instead of real data.
// Failing code (treated as if it were synchronous)
function getUserInfo() {
// 1. Ask the server (takes ~1s)
const data = fetch('https://api.example.com/user');
// 2. Log before data arrives!
console.log(data);
// Result: undefined or Promise { <pending> }
}
The syntax that tells JavaScript “do not move to the next line until the server answers|–is async / await.
Related: Promise on every API call
3. Cause
async - “this function is asynchronous|–
- Where: In front of a function declaration
- Role: Marks a normal function as async. An
asyncfunction always returns a Promise. - Rule: You may use
awaitonly inside a function declared withasync.
await - “pause here until the data arrives|–
- Where: Immediately before a slow Promise-returning call (API, etc.)
- Role: Suspends that line until the response is ready, then continues.
- Rule: Cannot stand alone - must live inside an
asyncfunction.
4. Solution
1) Old .then chains vs modern async / await
Past: nested .then (callback hell)
function fetchUserData() {
fetch('https://api.example.com/user')
.then((response) => response.json())
.then((user) => {
fetch(`https://api.example.com/posts/${user.id}`)
.then((response) => response.json())
.then((posts) => {
console.log('Fetched data:', posts);
});
});
}
Nested callbacks dig deeper and deeper - hard to read.
Modern: async / await
Frontend practice almost always prefers this shape. The code reads top-to-bottom like synchronous code:
// 1. Mark the function as async
async function fetchUserData() {
try {
// 2. Pause until the response arrives
const userResponse = await fetch('https://api.example.com/user');
const user = await userResponse.json();
// 3. Next line runs only after the above finishes
const postResponse = await fetch(`https://api.example.com/posts/${user.id}`);
const posts = await postResponse.json();
console.log('Fetched data:', posts);
} catch (error) {
// try/catch keeps error handling tidy
console.error('Failed to fetch data.', error);
}
}
5. Summary
For React/JavaScript API work, remember the formula: open with async, wait with await.
Interview tip
Q: From the client - server line of code,
awaitlooks synchronous - why call it async?A: From the browser?’s point of view it is still asynchronous: the UI does not freeze while you wait. Frontend work is judged from that browser perspective, so the name
asyncis correct.


