Synchronous vs Asynchronous

Why JavaScript doesn't wait — and what that means for your code.

Synchronous Code

Runs line by line. Each line waits for the previous one to finish.

console.log("First");   // 1️⃣ runs
console.log("Second");  // 2️⃣ waits, then runs
console.log("Third");   // 3️⃣ waits, then runs

// Output (always in order):
// "First"
// "Second"
// "Third"

Synchronous = sequential. Line 2 can't start until line 1 finishes. Predictable, ordered execution.

1 / 2

The Problem

What happens when synchronous code takes too long?

// Imagine fetching data synchronously (DON'T do this):
const data = fetchFromServer(); // ⏳ 3 seconds...
// NOTHING happens for 3 seconds:
// - Page freezes
// - Buttons don't respond
// - Animations stop
// - User thinks it's broken
console.log(data); // finally runs after 3s

Why this is a problem:

  • • JavaScript is single-threaded — one thing at a time
  • • Blocking the thread = blocking EVERYTHING (UI, events, animations)
  • • Network requests, file reads, timers all take time
  • • Users expect responsive interfaces

Asynchronous Code

Starts a task, moves on, comes back when it's done.

console.log("First");        // 1️⃣ runs immediately

setTimeout(() => {
  console.log("Second");     // 3️⃣ runs LATER (after 1s)
}, 1000);

console.log("Third");        // 2️⃣ runs immediately!

// Output:
// "First"
// "Third"    ← doesn't wait!
// "Second"   ← runs after 1 second

Async code doesn't block. setTimeout schedules work for later and immediately moves to the next line.

1 / 2

Synchronous vs Asynchronous:

SYNC

→ task 1 (wait...)

→ task 2 (wait...)

→ task 3 (wait...)

total: sum of all

ASYNC

→ start task 1

→ start task 2

→ start task 3

total: longest one

Event Loop Basics

How JavaScript handles async — the big picture.

// The Event Loop cycle:
// 1. Run all synchronous code (call stack)
// 2. Check if any async tasks are done
// 3. Run their callbacks
// 4. Repeat

console.log("A");         // 1. call stack

setTimeout(() => {
  console.log("B");       // 3. callback queue (after 0ms!)
}, 0);

console.log("C");         // 2. call stack

// Output: A, C, B
// Even with 0ms delay, setTimeout waits for
// synchronous code to finish first!

💡 The event loop ensures async callbacks only run after the current synchronous code finishes. This is why setTimeout(fn, 0) doesn't run immediately.

Common Patterns

The main ways to write asynchronous JavaScript.

// 1. Callbacks (oldest pattern):
fetchData(url, function(data) {
  process(data);
});

// 2. Promises (ES6):
fetchData(url)
  .then(data => process(data))
  .catch(err => handle(err));

// 3. Async/Await (ES2017 — cleanest):
async function load() {
  try {
    const data = await fetchData(url);
    process(data);
  } catch (err) {
    handle(err);
  }
}

We'll cover each pattern in depth in the following chapters. They all solve the same problem — handling operations that take time.

FAQ

Common questions about sync vs async.