Learn synchronous vs asynchronous JavaScript, and how using asynchronous code can improve program efficiency & responsiveness.

Introduction to Synchronous vs Asynchronous JavaScript

Welcome to this tutorial on Synchronous vs Asynchronous JavaScript.

In this guide, we will explore the two different ways of executing code in JavaScript. By the end, you will have a solid understanding of synchronous vs asynchronous code. And also, how to choose the right approach for your projects.

Synchronous JavaScript

When using synchronous JavaScript, the code executes sequentially, with each line of code being executed one after the other.

The program will wait for one line of code to finish executing before moving on to the next line of code.

This can cause a problem when a piece of code takes a long time to execute, such as when making an API call, as it will block the entire program until it finishes executing.

Asynchronous JavaScript

On the other hand, asynchronous JavaScript allows code to be executed out of order.

Instead of waiting for a piece of code to finish executing before moving on to the next line of code, asynchronous code allows other code to continue executing while the initial piece of code is still running.

This is useful for tasks that may take a long time to complete, such as retrieving data from a server or processing large amounts of data.

In order to achieve asynchronous behavior, JavaScript provides a number of tools such as callbacks, Promises, and async/await.

These tools allow developers to write code that can handle long-running tasks in a non-blocking manner, making the program more efficient and responsive.

Is JavaScript Asynchronous?

Yes, JavaScript is an asynchronous programming language.

In JavaScript, there are many tasks that take time to complete, such as network requests, file I/O, and user input.

Performing these tasks synchronously would cause the program to freeze, so JavaScript provides ways to handle these tasks asynchronously.

Asynchronous programming in JavaScript is typically done using callbacks, Promises, or the newer async/await syntax.

These techniques allow us to write code that can continue executing while a long-running task is being performed in the background.

By using asynchronous programming techniques, JavaScript can handle complex tasks and provide a more responsive user experience.

Example of Synchronous vs Asynchronous JavaScript

1. Example of JavaScript Synchronous code:

console.log("Starting program");

function addNumbers(a, b) {
  const sum = a + b;
  console.log(`The sum of ${a} and ${b} is ${sum}`);
}

addNumbers(2, 3);

console.log("Program ended");

In the above code, the console.log statements and the addNumbers function are executed in a sequential manner. The program will output the following:

Starting program
The sum of 2 and 3 is 5
Program ended

The program waits for the addNumbers function to finish executing before moving on to the next line of code.

2. Example of asynchronous code using callbacks:

console.log("Starting program");

function addNumbersAsync(a, b, callback) {
  setTimeout(() => {
    const sum = a + b;
    callback(sum);
  }, 1000);
}

addNumbersAsync(2, 3, (sum) => {
  console.log(`The sum of 2 and 3 is ${sum}`);
});

console.log("Program ended");

In the above code, the addNumbersAsync function simulates a long-running task by using the setTimeout function to delay execution for 1 second.

The function takes a callback function as an argument, which will be executed once the task is complete.

The program will output the following:

Starting program
Program ended
The sum of 2 and 3 is 5

The program does not wait for the addNumbersAsync function to finish executing before moving on to the next line of code.

Instead, the callback function is executed once the task is complete.

3. Example of asynchronous code using Promises:

console.log("Starting program");

function addNumbersAsync(a, b) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const sum = a + b;
      resolve(sum);
    }, 1000);
  });
}

addNumbersAsync(2, 3)
  .then((sum) => {
    console.log(`The sum of 2 and 3 is ${sum}`);
  });

console.log("Program ended");

In the above code, the addNumbersAsync function returns a Promise object instead of using a callback function.
The program will output the following:

Starting program
Program ended
The sum of 2 and 3 is 5

The program does not wait for the addNumbersAsync function to finish executing before moving on to the next line of code.

Instead, the Promise object is used to handle the asynchronous behavior.

Once the Promise is resolved, the then method is called to execute the next piece of code.

4. Example of asynchronous code using async/await:

console.log("Starting program");

function addNumbersAsync(a, b) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const sum = a + b;
      resolve(sum);
    }, 1000);
  });
}

async function run() {
  const sum = await addNumbersAsync(2, 3);
  console.log(`The sum of 2 and 3 is ${sum}`);
}

run();

console.log("Program ended");

In the above code, the run function is marked as async, which allows us to use the await keyword to wait for the addNumbersAsync function to complete before moving on to the next line of code.

The program will output the following:

Starting program
Program ended
The sum of 2 and 3 is 5

The program does not wait for the addNumbersAsync function to finish executing before moving on to the next line of code.

Instead, the await keyword is used to pause the execution of the run function until the Promise is resolved.

Once the Promise is resolved, the sum variable is assigned the resolved value, and the console.log statement is executed.

5. Handle asynchronous code in JavaScript using RxJx

RxJS is a popular library for handling asynchronous code that implements Reactive Extensions for JavaScript.

Reactive Extension is a library for composing asynchronous and event-based programs by using observable sequences.

Here’s an example of how to use RxJS to handle asynchronous code:

console.log("Starting program");

const { Observable } = rxjs;

function addNumbersAsync(a, b) {
  return new Observable((subscriber) => {
    setTimeout(() => {
      const sum = a + b;
      subscriber.next(sum);
      subscriber.complete();
    }, 1000);
  });
}

addNumbersAsync(2, 3)
  .subscribe((sum) => {
    console.log(`The sum of 2 and 3 is ${sum}`);
  });

console.log("Program ended");

In the above code, we’re creating an Observable object that will emit a value once the addNumbersAsync function has completed its task.

We’re using the subscribe method to listen for this value and log it to the console.

The program will output the following:

Starting program
Program ended
The sum of 2 and 3 is 5

The program does not wait for the addNumbersAsync function to finish executing before moving on to the next line of code.

The Observable object handles the asynchronous behavior, emitting a value once the task is completed.

The subscribe method then executes the next piece of code in response to the emitted value

Synchronous vs Asynchronous JavaScript Conclusion

In conclusion, understanding synchronous vs asynchronous JavaScript is important for any developer working with the language.

While synchronous code executes in a linear, step-by-step fashion. Asynchronous code enables concurrent execution of other code while a lengthy task runs in the background, leading to more efficient and responsive programs.

This can lead to more efficient, responsive programs that can handle complex tasks.

By using techniques such as callbacks, Promises, and async/await, developers can write asynchronous code that takes full advantage of JavaScript’s capabilities.