webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Tooling
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Forms
  12. 12Data and backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animations
  16. 16Testing
  17. 17Architecture
JavaScript · Lesson 14 of 17

Async: Promise and await

The event loop, async/await, running in parallel with Promise.all.

Updated

What synchronous and asynchronous mean

Synchronous = each line waits for the previous one to finish. Asynchronous = you start a slow operation (a network request, a timer, reading a file) and carry on with something else; the result comes later.

Why it matters: JS in the browser runs on a single thread — the same one that paints the page and responds to clicks. If it waited synchronously 2 seconds for a request, the page would freeze for 2 seconds.

The event loop — how it works

  1. The call stack — the code running right now.
  2. Slow operations are handed to the browser (network, timers), which does them in parallel.
  3. When one finishes, its callback goes into a queue.
  4. The event loop takes from the queue only when the stack is empty.

There are two queues, with different priorities:

Queue What goes in Priority
microtask Promise .then, await, queueMicrotask all of them run before the next macrotask
macrotask setTimeout, setInterval, events, I/O one per turn
console.log(1)
setTimeout(() => console.log(4))          // macrotask
Promise.resolve().then(() => console.log(3)) // microtask
console.log(2)
// 1, 2, 3, 4

What a Promise is

A Promise is an object that represents a value that's coming — like an order ticket: you don't have the food yet, but you have something you can wait on.

A Promise has 3 states:

State Means
pending still in progress
fulfilled done, it has a value
rejected it failed, it has an error

Once it has settled (fulfilled or rejected), the state never changes again.

const wait = ms => new Promise(resolve => setTimeout(resolve, ms))

fetch('/api/user')
  .then(res => res.json())      // runs on success
  .then(user => render(user))
  .catch(err => showError(err)) // runs on an error, anywhere in the chain

async / await — the same thing, written like synchronous code

async function loadUser(id) {
  try {
    const res = await fetch(`/api/users/${id}`)   // "pauses" the function until the response arrives
    return await res.json()
  } catch (error) {
    return null
  }
}
  • async before the function → it always returns a Promise.
  • await → waits for a Promise without blocking the page (only the current function "waits").
  • Errors are caught with a normal try/catch.
.then() async/await
Readability chains, callbacks top-to-bottom code
Errors .catch() try/catch
When short pipelines, outside async functions the default

Sequential vs parallel — the most common optimization

// ✗ sequential — the second starts after the first: 2 × the time
const user = await getUser()
const posts = await getPosts()

// ✓ parallel — both start at once
const [user, posts] = await Promise.all([getUser(), getPosts()])

Go sequential only when the second request depends on the result of the first.

Promise combinators — kinds and when

Method Settles when If one fails When
Promise.all all succeed fails immediately you need every result
Promise.allSettled all finish doesn't fail; you get each one's status you want partial results
Promise.race the first finishes (either way) depends on the first a timeout
Promise.any the first succeeds fails only if all fail several sources, any one is fine

Classic mistakes

  • forEach with async does not wait → for...of (sequential) or Promise.all(arr.map(...)) (parallel).
  • Forgetting await → you have a Promise instead of a value (user.name is undefined).
  • A Promise with no catch / try → unhandledrejection.
  • await in a loop when the requests are independent → slow.

Summary

  • JS has a single thread; slow operations are asynchronous so the page doesn't freeze.
  • A Promise = a future value: pending → fulfilled / rejected.
  • async/await + try/catch; Promise.all for parallel work.

Official sources

Exercises

Was this page helpful?

One tap — no account needed.