Skip to main content

Command Palette

Search for a command to run...

Synchronous vs Asynchronous JavaScript

Understanding How JavaScript Really Works Behind The Scenes

Updated
3 min readView as Markdown
Synchronous vs Asynchronous JavaScript

JavaScript looks simple when we write it.
But under the hood, it handles tasks in two very different ways:

  • Synchronous (one by one)

  • Asynchronous (non-blocking)

Understanding this difference is crucial if you want to build real-world applications like API's, dashboards, or web apps.

Let's break it down step by step.

What is Synchronous Code?

Synchronous code executes line by line, in order.

It waits for each task to finish before moving to the next.

Example:

console.log("Start");

console.log("Process");

console.log("End");

Output:

Start
Process
End

Think of it like:

Standing in a queue at a bank:

  • We can't move forward until the person ahead is done.

What is Asynchronous Code?

Asynchronous code allows JavaScript to start a task and move on without waiting.

It handles long task in the background.

Example:

console.log("Start");

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

console.log("End");

Output:

Start
End
Async Task Done

Visual Understanding

Synchronous Flow

  • Task 1 -> Task 2 -> Task 3

  • Everything waits in line

Asynchronous Flow

  • Task Start -> moves to next -> result comes later

  • No waiting = faster experience

Why JavaScript Needs Asynchronous Behavior?

JavaScript is single threaded
It can do only one thing at a time.

So what happens if something takes long?

Example:

  • Fetching data from API

  • Reading a file

  • Waiting for user input

If JS waited for each of these --> our app would freeze

That's why async behavior exists:

  • Keeps UI responsive

  • Prevents blocking

  • Improves performance

Real World Examples

1. API Calls

console.log("Fetching data...");

fetch("https://api.example.com/data")
  .then(res => res.json())
  .then(data => console.log(data));

console.log("Done");

Output:

Fetching data...
Done
(data comes later)

2. Timer

setTimeout(() => {
  console.log("Runs after 3 seconds");
}, 3000);

JS doesn’t wait — it continues executing other code.

Problems with Blocking Code

Imagine this:

function blockFor3Sec() {
  const start = Date.now();
  while (Date.now() - start < 3000) {}
}

console.log("Start");

blockFor3Sec();

console.log("End");

Output:

Start
(wait 3 seconds...)
End

Issues:

  • UI freezes

  • No clicks, no scroll, nothing works

  • terrible user experience

Blocking vs Non-blocking

Type Behavior Example
Blocking Waits for tasks to finish Heavy Calculations
Non-Blocking Moves ahead, handles later API calls, timers

Everyday Analogy

Ordering Pizza

Synchronous:

  • Order pizza

  • wait at shop for 30 mins

  • Then continue your day

Asynchronous:

  • Order pizza

  • Go home, watch Netflix

  • Pizza arrives later

Suggestion For Writing Better Async Code

  1. Start Simple

    • Understand execution order before jumping into advance concept
  2. Prefer async patterns

    • Use

      • Promises

      • async/await

  3. Avoid blocking code

    • never use heavy loops on main thread.
  4. Think in background tasks.

    • Ask yourself: "Can this run without the rest of the app"
  5. Use real world thinking

    • Always map code to real-life situations --- it makes learning easier.

Final Thoughts

  • Synchronous = step by step execution

  • Asynchronous = non-blocking, efficient execution

JavaScript uses async behavior to:

  • Stay fast

  • Stay responsive

  • Handle real world tasks