Skip to main content

Command Palette

Search for a command to run...

Synchronous vs Asynchronous JavaScript

Updated
4 min read
Synchronous vs Asynchronous JavaScript

JavaScript programming often brings two contrasting styles to the table: synchronous and asynchronous. Knowing when to use each can make or break the performance of your application. Let’s break down these concepts and understand their significance.

What synchronous code means

Synchronous code runs in a sequential manner. Each line of code must finish executing before the next one begins. Imagine you're at a famous Himachal Pradesh restaurant, waiting for your order. The chef prepares one dish at a time. If you ordered Chole Bhature and the chef is busy making Aloo Paratha, you wait until the former is done. In programming, this means the browser is blocked from doing anything else until the code completes its current task. If you're making API calls or performing time-consuming calculations, everything else halts until it finishes.

function syncTask() {
    console.log('Task 1: Start');
    for (let i = 0; i < 1000000000; i++) {} // Simulating a long task
    console.log('Task 1: End');
}

syncTask();
console.log('Next Task');

In this example, 'Next Task' waits until the loop in syncTask finishes. The user experience suffers if the task takes too long.

What asynchronous code means

Asynchronous code allows multiple tasks to be executed concurrently. This is like being at the same Himachal restaurant, where you place your order and then chat with friends while waiting. The chef prepares your dish without blocking other orders. JavaScript uses callbacks, promises, or async/await to handle asynchronous operations. You give the browser a task, and it continues working on other tasks while waiting for that task to finish.

function asyncTask() {
    console.log('Task 1: Start');
    setTimeout(() => {
        console.log('Task 1: End');
    }, 2000);
}

asyncTask();
console.log('Next Task');

Here, 'Next Task' runs immediately after 'Task 1: Start', without waiting for the timeout to finish. This non-blocking behavior enhances user experience.

Why JavaScript needs asynchronous behavior

JavaScript is single-threaded, which means it can handle one task at a time. In web applications, users expect fast interactions. Imagine a cricket match where the live score updates every few seconds. If the score fetching was synchronous, the entire web page would freeze while waiting for the latest score. This would frustrate viewers. Asynchronous behavior allows JavaScript to perform I/O operations like fetching data, reading files, or waiting for timers without halting the main thread.

Examples like API calls or timers

APIs are a great example of where asynchronous code shines. Consider a weather application that fetches data from an API. If the app waits synchronously for the response, users stare at a spinning loader, losing interest. Instead, the app can fetch the data asynchronously, allowing users to navigate or interact with other features. Here’s how that looks:

function fetchWeather() {
    console.log('Fetching weather...');
    fetch('https://api.weatherapi.com/v1/current.json?key=YOUR_API_KEY&q=Shimla')
        .then(response => response.json())
        .then(data => {
            console.log(`Current temperature in Shimla: ${data.current.temp_c}°C`);
        });
}

fetchWeather();
console.log('You can still use the app!');

In this case, the user can continue using the app while the weather data is being fetched. Timers also use asynchronous behavior. Here’s an example using setTimeout:

console.log('Starting timer...');
setTimeout(() => {
    console.log('Timer finished!');
}, 3000);
console.log('Doing other things...');

The timer runs in the background, allowing other code to execute in the meantime. This non-blocking feature is a game changer.

Problems that occur with blocking code

Blocking code can create a frustrating user experience. Imagine you’re watching a movie at home, and suddenly the Wi-Fi drops. The streaming service buffers indefinitely. This is what happens with synchronous code in JavaScript. Users might face unresponsive UI, long loading times, and an overall bad experience. Any long-running task can lead to the dreaded “page unresponsive” message in browsers.

Another issue arises from the lack of feedback. Users expect immediate responses to their actions. If your app freezes while processing a task, you lose their trust. They want to see progress or at least a spinning indicator to understand something is happening.

In the context of web applications, blocking code can lead to performance bottlenecks. For example, a website that processes images synchronously will frustrate users if they need to upload multiple files. The entire interface could become unresponsive, leading to higher bounce rates and lost opportunities.

In conclusion, understanding synchronous and asynchronous JavaScript is vital for creating efficient and user-friendly applications. While synchronous code has its place for simple tasks, asynchronous code is the unsung hero that keeps your apps responsive and engaging. Get comfortable with it, and you’ll see the difference in your projects.