Skip to main content

Command Palette

Search for a command to run...

Understanding Synchronous and Asynchronous JavaScript

Updated
4 min read

When learning JavaScript, one of the most important concepts to understand is how code executes. JavaScript can run code synchronously or asynchronously, and understanding the difference between these two execution styles helps explain how JavaScript handles tasks like API requests, timers, and user interactions.

In this article, we will explore:

  • What synchronous code means

  • What asynchronous code means

  • Why JavaScript needs asynchronous behavior

  • Examples such as API calls and timers

  • Problems that occur with blocking code


What Is Synchronous Code?

Synchronous code runs step by step, in the exact order it appears in the program.

Each line of code must finish executing before the next line begins.

Example:

console.log("Step 1");
console.log("Step 2");
console.log("Step 3");

Output:

Step 1
Step 2
Step 3

Execution happens in a strict sequence:

Step 1 → Step 2 → Step 3

JavaScript reads the program from top to bottom and executes each instruction one at a time.


Step-by-Step Execution Example

Consider the following example:

function task1() {
  console.log("Task 1 completed");
}

function task2() {
  console.log("Task 2 completed");
}

task1();
task2();

Execution order:

task1() runs
↓
"Task 1 completed" printed
↓
task2() runs
↓
"Task 2 completed" printed

Nothing happens simultaneously. Each task waits for the previous one to finish.


What Is Asynchronous Code?

Asynchronous code allows JavaScript to start a task and continue executing other code without waiting for that task to finish.

Example using setTimeout:

console.log("Start");

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

console.log("End");

Output:

Start
End
Timer finished

Execution order visually:

Start
↓
Timer scheduled
↓
End
↓
(after 2 seconds)
Timer finished

Even though the timer appears earlier in the code, JavaScript does not wait for it to finish.


Why JavaScript Needs Asynchronous Behavior

JavaScript is commonly used in environments where waiting for tasks can take time. For example:

  • Fetching data from an API

  • Reading files

  • Waiting for user input

  • Running timers

If JavaScript waited for each of these operations to complete before continuing, the application would become slow and unresponsive.

Asynchronous behavior allows JavaScript to continue running other code while waiting for results.


Everyday Example: Waiting for Data

Imagine ordering food at a restaurant.

Synchronous scenario

Order food
Wait for food to cook
Eat
Leave

You cannot do anything else while waiting.

Asynchronous scenario

Order food
Talk with friends
Food arrives later
Eat

While waiting for the food, you can continue doing other activities.

JavaScript works in a similar way when handling asynchronous operations.


Example: API Call

Fetching data from a server is a common asynchronous task.

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

fetch("https://api.example.com/data")
  .then(response => response.json())
  .then(data => console.log("Data received:", data));

console.log("Other code running...");

Output flow:

Requesting data...
Other code running...
Data received: ...

The program does not stop while waiting for the API response.


Blocking vs Non-Blocking Code

Blocking Code (Synchronous)

Blocking code prevents the program from continuing until the current task finishes.

Example:

Start task
Wait until task finishes
Continue program

If the task takes a long time, the program becomes unresponsive.


Non-Blocking Code (Asynchronous)

Non-blocking code allows the program to continue running while waiting for tasks to complete.

Example:

Start task
Continue program
Task finishes later
Handle result

This behavior keeps applications responsive.


Problems with Blocking Code

Blocking operations can cause several issues:

Slow Applications

If the program waits for long tasks, everything else stops.


Poor User Experience

In web applications, blocking code can freeze the interface, making the page appear unresponsive.


Reduced Performance

Programs cannot perform multiple operations efficiently when blocked.

Asynchronous programming helps avoid these problems.


Conclusion

Understanding synchronous and asynchronous behavior is essential for working with JavaScript effectively.

Key points to remember:

  • Synchronous code runs step by step in order

  • Asynchronous code allows tasks to run without blocking the program

  • JavaScript uses asynchronous behavior for tasks like API requests and timers

  • Blocking code can slow down applications and harm user experience

  • Asynchronous programming keeps applications responsive and efficient

As you continue learning JavaScript, concepts such as callbacks, promises, and async/await will help you manage asynchronous operations more effectively.