Realworld Example to remember Callbacks, Promises, and Async/Await in JavaScript

Realworld Example to remember Callbacks, Promises, and Async/Await in JavaScript

In the ever-evolving landscape of web development, JavaScript stands as the backbone of the modern web. As developers, we often find ourselves working with asynchronous operations, which can be a bit daunting at first.

Callbacks, Promises, and Async/Await are fundamental tools in JavaScript that allow us to handle these asynchronous operations with finesse.

In this article, we'll delve into these concepts using analogies and JavaScript code examples to help you master them.

Understanding Callbacks

Callbacks are like waiting in a queue at your favorite coffee shop. You place your order, and the barista tells you they're busy making coffee for others. Instead of standing in line and wasting your time, you give them your phone number and wait for a text message when your coffee is ready.

In JavaScript, callbacks work in a similar way. When you initiate an asynchronous task, like fetching data from a server, you don't want your entire program to halt. So, you provide a callback function to be executed when the task is complete.

Here's a simple JavaScript callback example:

function fetchData(callback) {
  setTimeout(() => {
    const data = "Here's your data!";
    callback(data);
  }, 2000);
}

function processFetchedData(data) {
  console.log("Processing data:", data);
}

fetchData(processFetchedData);

In this example, the fetchData function simulates an asynchronous operation and executes the processFetchedData callback when it's done.

Introducing Promises

Promises are like a promise ring. When you give someone a promise ring, it represents a commitment. You assure them that you'll fulfill your promise, and they can trust you. The promise ring itself is the "promise," and it holds the commitment to fulfill something.

In JavaScript, a Promise is an object representing a value that may not be available yet but will be resolved at some point in the future. Let's rewrite the previous example using Promises:

function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = "Here's your data!";
      resolve(data);
    }, 2000);
  });
}

fetchData()
  .then(data => {
    console.log("Processing data:", data);
  })
  .catch(error => {
    console.error("Error:", error);
  });

Here, the fetchData function returns a Promise, and we can chain .then() to handle the resolved value and .catch() to handle errors.

Going Async with Async/Await

Imagine you are waiting for packages to arrive from different couriers, and you need to open each package as soon as it arrives. You don't want to open them one by one because it would be time-consuming.

You need a way to open each package as it arrives without waiting for the others. This is where Async/Await comes into play.

Async/Await is like hiring an assistant who takes care of receiving and opening packages while you focus on other tasks. Your assistant makes sure to open each package as it arrives without any delay.

In JavaScript, Async/Await is a way to write asynchronous code that looks synchronous. Let's rewrite the example once more:

async function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      const data = "Here's your data!";
      resolve(data);
    }, 2000);
  });
}

async function processFetchedData() {
  try {
    const data = await fetchData();
    console.log("Processing data:", data);
  } catch (error) {
    console.error("Error:", error);
  }
}

processFetchedData();

The fetchData function remains the same, but now, the processFetchedData function uses async and await, making the asynchronous code look much more like synchronous code.

Conclusion

Callbacks, Promises, and Async/Await are powerful tools in JavaScript for managing asynchronous operations. Think of them as strategies to handle waiting in line for coffee, making promises with commitment, and having an assistant to manage your packages.