DeployU
Interviews / Frontend Engineering / What are the different ways to handle asynchronous operations in JavaScript?

What are the different ways to handle asynchronous operations in JavaScript?

conceptual Asynchronous Programming Interactive Quiz Code Examples

The Scenario

You are a frontend engineer at a social media company. You are writing a new feature that needs to make an API call to get some data and then update the UI with the data.

You are not sure which of the different ways to handle asynchronous operations in JavaScript you should use.

The Challenge

Explain the different ways to handle asynchronous operations in JavaScript. What are the pros and cons of each approach, and which one would you choose for this use case?

Wrong Approach

A junior engineer might only be aware of callbacks. They might not be aware of Promises or `async/await`, or the trade-offs between them.

Right Approach

A senior engineer would be able to provide a detailed explanation of all the different ways to handle asynchronous operations in JavaScript. They would also be able to explain the trade-offs between each approach and would have a clear recommendation for which one to use in this use case.

Step 1: Understand the Different Ways to Handle Asynchronous Operations

MethodDescription
CallbacksA function that is passed as an argument to another function and is executed when the other function has completed.
PromisesAn object that represents the eventual completion (or failure) of an asynchronous operation.
async/awaitSyntactic sugar on top of Promises that makes asynchronous code look and behave more like synchronous code.

Step 2: Choose the Right Tool for the Job

For our use case, we should use async/await. This is because it is the most modern and readable way to write asynchronous code in JavaScript.

Step 3: Code Examples

Here are some code examples that show the difference between the three approaches:

Callbacks:

function getData(callback) {
  setTimeout(() => {
    callback(null, 'some data');
  }, 1000);
}

getData((err, data) => {
  if (err) {
    // ... (handle the error) ...
  } else {
    // ... (use the data) ...
  }
});

Promises:

function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('some data');
    }, 1000);
  });
}

getData()
  .then(data => {
    // ... (use the data) ...
  })
  .catch(error => {
    // ... (handle the error) ...
  });

async/await:

async function getData() {
  const data = await new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('some data');
    }, 1000);
  });
  // ... (use the data) ...
}

Practice Question

You want to make two API calls in parallel and then do something with the results of both calls. Which of the following would you use?