DEV Community

Cover image for Asynchronous JavaScript: From Callbacks to Async/Await - A Journey Through Evolution
Ashutosh Kumar
Ashutosh Kumar

Posted on

3 1 1 1 1

Asynchronous JavaScript: From Callbacks to Async/Await - A Journey Through Evolution

Asynchronous programming in JavaScript can be a bit of a funky headache, especially when dealing with complex code. In the early days of JavaScript, callbacks were the groovy go-to method for handling asynchronous operations.

If you prefer to learn through videos, check out this resource that offers a clear explanation of these concepts using examples From Callback to async/await: A Journey through Asynchronous Javascript

callback

Callbacks

Callbacks are functions that are passed as arguments to other functions and are invoked when an asynchronous operation completes. For example:

function getData(callback) {
  // simulate an asynchronous operation
  setTimeout(() => {
    callback('Hello World!');
  }, 1000);
}

// use the getData function with a callback
getData((data) => {
  console.log(data); // output: Hello World!
});
Enter fullscreen mode Exit fullscreen mode

Dealing with multiple levels of nesting in callbacks can be a real headache, leading to a phenomenon known as "callback hell." It can be a real hassle when writing complex code in JavaScript. To help you understand this concept better, let me show you an example.

function getData(callback) {
  setTimeout(() => {
    callback('Hello');
    setTimeout(() => {
      callback('World');
      setTimeout(() => {
        callback('!');
      }, 1000);
    }, 1000);
  }, 1000);
}

// use the getData function with a callback
getData((data) => {
  console.log(data); // output: Hello
  getData((data) => {
    console.log(data); // output: World
    getData((data) => {
      console.log(data); // output: !
    });
  });
});
Enter fullscreen mode Exit fullscreen mode

3rd callback 4th callback 5th callback

Promises

Thankfully, the introduction of Promises offered a more elegant solution to handling asynchronous code. Promises represent a value that may not be available yet, but will be at some point in the future. With Promises, we can chain asynchronous operations and handle errors more efficiently. Here's an example:

function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Hello World!');
    }, 1000);
  });
}

// use the getData function with Promises
getData()
  .then((data) => {
    console.log(data); // output: Hello World!
  })
  .catch((error) => {
    console.log(`Error fetching data: ${error}`);
  });
Enter fullscreen mode Exit fullscreen mode

While Promises are a significant improvement over callbacks, they still resulted in long chains of then and catch statements, which could make the code hard to read and understand. Not so fun, right?

async/await

And then came the dynamic duo - async and await! These two made a game-changing entry, allowing developers to write asynchronous code that reads like synchronous code. It's like having a superhero sidekick! Instead of chaining Promises, await can be used to pause the function execution until the Promise resolves. This results in cleaner, more readable code that's easier to maintain and debug. How cool is that?

async function getData() {
  try {
    const data = await fetch('/data');
    return data;
  } catch (error) {
    console.log(`Error fetching data: ${error}`);
  }
}

// use the getData function with async/await
(async () => {
  const data = await getData();
  console.log(data); // output: fetched data
})();
Enter fullscreen mode Exit fullscreen mode

As you can see, async/await significantly simplifies asynchronous programming in JavaScript. No more callback hell, no more long chains of then and catch statements. Just clean, concise code that's easy to read and understand.

SurveyJS custom survey software

Build Your Own Forms without Manual Coding

SurveyJS UI libraries let you build a JSON-based form management system that integrates with any backend, giving you full control over your data with no user limits. Includes support for custom question types, skip logic, an integrated CSS editor, PDF export, real-time analytics, and more.

Learn more

Top comments (0)

Cloudinary image

Video API: manage, encode, and optimize for any device, channel or network condition. Deliver branded video experiences in minutes and get deep engagement insights.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay