Skip to main content

Command Palette

Search for a command to run...

Synchronous and Asynchronous JavaScript

Updated
7 min read
Synchronous and Asynchronous JavaScript

JavaScript looks simple when we first start learning it.

We write one line after another, and the program runs step by step.

But when websites start doing things like:

  • Fetching data from APIs

  • Waiting for user clicks

  • Running timers

  • Uploading files

  • Showing notifications

then JavaScript behaves differently.

This is where Synchronous and Asynchronous programming come into the picture.


What is Synchronous Code?

Synchronous code means:

JavaScript executes one line at a time in order.

The next line waits until the current line finishes.


Simple Example

console.log("Start");

console.log("Learning JavaScript");

console.log("End");

Output

Start
Learning JavaScript
End

Start Learning JavaScript End


How It Works

Step 1 → Start

Step 2 → Learning JavaScript

Step 3 → End

Everything runs one after another.


Real Life Example

Imagine you are standing in a queue at a shop.

The next person can only go after the current person finishes.

This is synchronous behavior.


Synchronous Execution Flowchart

 ┌──────────┐
 │     Start      │
 └────┬─────┘
         │
         ▼
┌───────────────┐
│ Execute Line 1         │
└────┬──────────┘
        │
        ▼
┌───────────────┐
│ Execute Line 2         │
└────┬──────────┘
        │
        ▼
┌───────────────┐
│ Execute Line 3         │
└────┬──────────┘
        │
        ▼
 ┌──────────┐
 │   End          │
 └──────────┘

Problem with Synchronous Code

Sometimes tasks take time.

Examples:

  • Fetching data from server

  • Downloading image

  • Reading file

  • Waiting 5 seconds

  • Database operations

If JavaScript waits for these tasks completely, the whole application freezes.

This is called blocking.


Blocking Code Example

console.log("Start");

for(let i = 0; i < 10000000000; i++) {
    // heavy task
}

console.log("End");

What Happens?

The loop takes time.

So "End" waits until the loop finishes.

During this time:

  • UI may freeze

  • Buttons may stop working

  • Website feels slow


Blocking Flow

 Start
  │
  ▼
 Heavy Task Running...
  │
  │  (Everything waits)
  │
  ▼
 End

Why JavaScript Needs Asynchronous Behavior

Websites must stay responsive.

Imagine:

  • You click a button

  • Data is loading from server

  • Website freezes for 10 seconds

Bad user experience.

So JavaScript uses asynchronous behavior to handle long tasks in the background.


What is Asynchronous Code?

Asynchronous code means:

JavaScript does not wait for some tasks to finish.

Instead:

  • It starts the task

  • Moves to next line

  • Comes back later when task completes


Simple Async Example

console.log("Start");

setTimeout(() => {
    console.log("Timer Finished");
}, 2000);

console.log("End");

Output

Start
End
Timer Finished

Why Did This Happen?

Because setTimeout() is asynchronous.

JavaScript says:

"You run in background. I will continue other work."


Async Timeline Diagram

Time →
────────────────────────────────

Main Thread:
Start ─────── End ──────────────

Background Timer:
      └── Waiting 2 sec ───────┘

Callback Queue:
                     Timer Finished

Real Life Example

Suppose you order food online.

You do not sit doing nothing while food cooks.

You continue:

  • watching TV

  • using phone

  • studying

When food arrives, delivery notifies you.

This is asynchronous behavior.


Blocking vs Non-Blocking Code

Blocking Code Non-Blocking Code
Stops execution Does not stop execution
Waits for task completion Continues running
Slower experience Better performance
Can freeze UI Keeps UI responsive

Example Comparison

Blocking Example

console.log("A");

alert("Stop Everything");

console.log("B");

The alert blocks everything.

Non-Blocking Example

console.log("A");

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

console.log("B");

Output:

A
B
Async Task

Common Asynchronous Operations in JavaScript


1. Timers

setTimeout(() => {
   console.log("Hello");
}, 1000);

2. API Calls

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

JavaScript does not wait for internet response.


3. User Events

button.addEventListener("click", () => {
   console.log("Button Clicked");
});

JavaScript waits for user interaction asynchronously.


How JavaScript Handles Async Tasks

JavaScript is:

  • Single-threaded

  • But asynchronous

This confuses many beginners.


JavaScript Has:

  • Call Stack

  • Web APIs

  • Callback Queue

  • Event Loop

Together they manage async behavior.


Architecture Diagram

            ┌─────────────────┐
            │       Call Stack          │
            └────────┬────────┘
                          │
                          ▼
            ┌─────────────────┐
            │        Web APIs           │
            │     setTimeout etc        │
            └────────┬────────┘
                          │
                          ▼
            ┌─────────────────┐
            │      Callback Queue       │
            └────────┬────────┘
                          │
                          ▼
            ┌─────────────────┐
            │       Event Loop          │
            └─────────────────┘

Understanding the Event Loop

The Event Loop continuously checks:

"Is Call Stack empty?"

If YES:

It pushes callback functions from queue into stack.


Example

console.log("Start");

setTimeout(() => {
   console.log("Timer");
}, 0);

console.log("End");

Execution Steps

Step 1

Start printed 

Step 2

setTimeout goes to Web API.


Step 3

End Printed

Step 4

Timer callback enters Callback Queue.


Step 5

Event Loop checks stack.

Stack empty?

YES.

So callback executes.


Final Output

Start
End 
Timer

Event Loop Visualization

Call Stack:
┌──────────┐
│ console        │
└──────────┘

Web API:
┌──────────┐
│ setTimeout     │
└──────────┘

Callback Queue:
┌──────────┐
│ callback       │
└──────────┘

Callback Functions

Callbacks are functions passed into another function.


Example

function greet(name, callback) {
    console.log("Hello " + name);

    callback();
}

greet("Rahul", () => {
    console.log("Callback Executed");
});

Output

Hello Rahul
Callback Executed

Problem with Callbacks

Too many callbacks create messy code.

This is called:

Callback Hell


Example

loginUser(() => {
   getProfile(() => {
      getPosts(() => {
          getComments(() => {

          });
      });
   });
});

Hard to read and maintain.


Promises

Promises solve callback hell.

A Promise represents:

Future Result

States:

  • Pending

  • Resolved

  • Rejected


Promise Example

const promise = new Promise((resolve, reject) => {

    let success = true;

    if(success) {
        resolve("Data Loaded");
    } else {
        reject("Error");
    }

});

promise
.then(data => console.log(data))
.catch(err => console.log(err));

Async Await

Modern way to handle asynchronous code.

Cleaner and easier.


Example

async function getData() {

   const response = await fetch("https://api.com");

   const data = await response.json();

   console.log(data);
}

Why Async Await is Better

  • Cleaner syntax

  • Looks synchronous

  • Easier debugging

  • Better readability


Complete Async Flow

User Action
    │
    ▼
JavaScript Starts API Call
    │
    ▼
API Works in Background
    │
    ▼
JavaScript Continues Other Work
    │
    ▼
Response Arrives
    │
    ▼
Callback / Promise Executes

Everyday Examples of Asynchronous Behavior

Situation

Async Behavior

Ordering food

Wait while doing other work

Downloading file

Continue browsing

Sending WhatsApp message

Message delivered later

Uploading image

UI still works


Key Difference Summary

Synchronous

Asynchronous

Executes line by line

Does not wait

Blocking

Non-blocking

Simple

Efficient

Slower for longer tasks

Better performance

Freezes UI sometimes

Smooth experience


Conclusion

Understanding synchronous and asynchronous programming is one of the most important concepts in JavaScript.

Without async behavior:

  • Websites would freeze

  • APIs would block everything

  • Applications would feel slow

Asynchronous programming makes modern web applications fast and responsive.

Thank you for reading this blog.
I hope this helped you clearly understand synchronous and asynchronous JavaScript. Your feedback is always appreciated.