Skip to main content

The modern way to write async code

async/await is syntactic sugar on top of Promises. It lets you write async code that reads top-to-bottom, just like synchronous code. This is what you’ll use 90% of the time.
Two keywords, two rules:
  • async goes before the function declaration — marks it as asynchronous
  • await goes before a Promise — pauses execution until the Promise resolves

async functions

Adding async to a function does one thing: it makes the function always return a Promise.
This means any function that uses await inside it must be marked async.

Arrow function version

await — pausing until the Promise resolves

await pauses the function until the Promise settles. The function doesn’t block the page — it just pauses internally while other code keeps running.
await pauses the current async function, not the entire program. Other code outside the function continues to run. That’s why line 4 prints before lines 2 and 3.

Error handling with try/catch

Use try/catch to handle errors in async functions — just like you would in Python:
try/catch catches both:
  • Network errors — when fetch itself fails (no internet, DNS failure)
  • Errors you throw — like when response.ok is false

try/catch/finally

finally is perfect for resetting loading states. It runs regardless of success or failure, so you don’t need to set loading = false in both the try and catch blocks.

Sequential vs parallel

Sequential — one after another

When each request depends on the previous result:

Parallel — all at once

When requests are independent, use Promise.all() with await:
A common mistake is using await for every request even when they don’t depend on each other. If two requests are independent, run them in parallel with Promise.all().

Comparing to Python

The syntax is nearly identical. The big difference: in Python, async is opt-in (most code is synchronous). In JavaScript, any code that touches the network is async by default.

The pattern you’ll use everywhere

This is the complete async/await pattern for API calls:
You’ll see this exact pattern in nearly every web application. Learn it once, use it everywhere.

What’s next?

You understand async/await. Now let’s put it to work — making real HTTP requests to your FastAPI backend with fetch.

Fetching data from APIs

Make GET, POST, PUT, and DELETE requests with fetch