Asynchronous JavaScript
The Problem: Waiting Without Freezing
JavaScript is single-threaded — it can only do one thing at a time. But real programs constantly need to wait: for a network response, a file to load, a timer to fire.
If waiting meant blocking — freezing everything until the wait is over — no webpage would ever be usable.
The solution is asynchronous code: start the task, move on, come back when it's done.
Run this and notice the order:
setTimeout schedules a callback for later — even "0ms later" means after the current code is done. JavaScript finishes what it's doing, then checks if any scheduled callbacks are ready. This scheduling mechanism is called the event loop.
setTimeout and setInterval
The Callback Problem
Callbacks work — but they don't compose cleanly. What if you need three things in sequence, each waiting for the previous?
This is callback hell — each step forced to live inside the previous one. Error handling is a nightmare. This is the problem Promises were invented to solve.
Promises
A Promise is an object that represents a value that isn't available yet. It is in one of three states: pending, fulfilled, or rejected.
new Promise takes a function with two parameters: resolve (call when done) and reject (call on failure). The value passed to resolve becomes what .then() receives.
Chaining Promises
The key promise superpower: .then() returns a new promise, so you chain instead of nesting:
Handling Errors with .catch()
One .catch() at the end of a chain handles any rejection from any step above it.
async / await — Promises with a Cleaner Face
async/await is not a new feature — it is syntax that makes promises look synchronous. Under the hood it is exactly the same promise chain:
await pauses execution of the async function until the promise resolves — but does not block the rest of the program.
try/catch with async/await
Running Promises in Parallel
await in sequence waits for each step before starting the next. Promise.all starts everything simultaneously:
Sequential waits ~240ms. Parallel waits ~100ms — the longest single request. Use Promise.all when tasks are independent of each other.
What You Have Learned
Async JavaScript is about one thing: doing work later, without freezing now.
The key ideas:
- JavaScript is single-threaded — async is how it handles waiting without blocking
- The event loop checks for and runs scheduled callbacks after current code finishes
- Callbacks work but nest badly — callback hell is a real maintenance problem
- Promises solve nesting with flat
.then()chains and a single.catch() async/awaitis promises with synchronous-looking syntax — same machinery, far more readableawaitpauses your function without pausing the programPromise.allruns multiple async operations in parallel — use it when tasks are independent
In the next lesson: Classes & Object-Oriented Programming — blueprints for creating many objects of the same shape, with inheritance, private fields, and a cleaner syntax for everything you already know about objects.