Skip to main content

Command Palette

Search for a command to run...

Synchronous vs Asynchronous JavaScript: Why Your Code Doesn’t Always Run in Order

Updated
4 min read
Synchronous vs Asynchronous JavaScript: Why Your Code Doesn’t Always Run in Order

“Why didn’t my code run line by line?”

You write this:

console.log("Start");

setTimeout(() => {
  console.log("Inside timeout");
}, 2000);

console.log("End");

And expect:

Start  
(wait 2 seconds)  
Inside timeout  
End  

But you actually get:

Start  
End  
Inside timeout  

Confusing?

Welcome to the world of asynchronous JavaScript.


What is synchronous code?

Synchronous code runs line by line, in order.

One task at a time

Next task starts only after previous finishes


Example

console.log("A");
console.log("B");
console.log("C");

Output:

A  
B  
C  

Real-life analogy

Think of a single cashier line 🧾

  • One customer at a time

  • Others must wait

That’s synchronous behavior


Visual timeline

A → B → C → Done

What is asynchronous code?

Asynchronous code allows multiple tasks to happen without blocking.

Long tasks don’t stop the flow

Other code continues executing


Example

console.log("Start");

setTimeout(() => {
  console.log("Async Task");
}, 2000);

console.log("End");

What happens?

  • "Start" runs

  • Timer starts in background

  • "End" runs immediately

  • After 2 seconds → async task runs


Visual timeline

Start → End → (wait) → Async Task

Real-life analogy

Think of ordering food

  • You order food

  • Instead of waiting there, you sit and relax

  • Food comes later

You didn’t block your time


Why JavaScript needs asynchronous behavior

JavaScript runs on a single thread (one task at a time).

Now imagine:

while(true) {}

This blocks everything forever


Problem with blocking code

If JS was only synchronous:

  • UI would freeze

  • Apps would feel slow

  • No real-time interaction


Example (bad scenario)

function longTask() {
  for (let i = 0; i < 1e9; i++) {}
}

console.log("Start");
longTask();
console.log("End");

"End" waits until longTask finishes


Asynchronous saves the day

With async behavior:

  • Heavy tasks run in background

  • UI remains responsive

  • Users don’t feel stuck


Common async operations

  • API calls

  • Timers

  • File reading

  • Database queries


Example: API call

async function getData() {
  const res = await fetch("https://api.example.com");
  const data = await res.json();
  console.log(data);
}

While data is loading, app keeps running


Behind the scenes (simple idea)

JavaScript uses:

  • Call stack

  • Web APIs

  • Task queue


Simplified flow

Code → Call Stack → Async Task → Queue → Back to Stack

Visual concept

Main Thread → Executes sync code
          ↓
Async task → goes to background
          ↓
When ready → comes back to queue
          ↓
Executed later

Synchronous vs Asynchronous

Feature Synchronous Asynchronous
Execution Line by line Non-blocking
Speed Slower for heavy tasks Faster overall
Blocking Yes No
Use case Simple tasks APIs, timers

Easy memory trick

Sync = wait

Async = don’t wait


Practical example


Synchronous thinking

const data = fetchData(); // assume immediate
console.log(data);

Asynchronous reality

fetchData().then(data => {
  console.log(data);
});

Common confusion

“Async means parallel?”

Not exactly.

JavaScript is still single-threaded,

but it delegates tasks to background systems.


Final thoughts

Understanding sync vs async is foundational.

Everything builds on this:

  • Promises

  • Async/Await

  • Event loop

If you understand this well, you unlock real JavaScript power