Sitemap
Dev Genius

Coding, Tutorials, News, UX, UI and much more related to development

The Ultimate Beginner’s Guide to Callbacks, Promises, and Async/Await in JavaScript

3 min readMay 27, 2024

--

If you’re learning JavaScript, you’ll soon encounter asynchronous programming. This means doing tasks that take time (like fetching data from the internet) without freezing your entire app. JavaScript provides three main ways to handle asynchronous tasks: callbacks, promises, and async/await. This guide will explain each method in simple terms, showing how they work and how they compare.

Callbacks

Basics:

A callback is a function passed into another function as an argument, which is then invoked (called back) inside the outer function to complete some kind of routine or action.

Example:

Imagine you order a pizza. The pizza place will call you (callback) when your pizza is ready.

function orderPizza(callback) {
console.log("Pizza ordered. It will be ready soon.");
setTimeout(() => {
callback("Your pizza is ready!");
}, 2000); // Simulates a 2-second pizza preparation time
}
function notifyUser(message) {
console.log(message);
}
orderPizza(notifyUser);

Problems with Callbacks

- Callback Hell: When you have multiple asynchronous tasks, callbacks can get deeply nested and hard to read.

- Error Handling: Managing errors can be tricky and makes the code messy.

Promises

Basics:

A promise is an object representing the eventual completion (or failure) of an asynchronous operation and its resulting value.

Example:

Think of a promise as a pizza delivery tracker that updates you on the status: “Pending,” “Fulfilled,” or “Rejected.”

function orderPizza() {
return new Promise((resolve, reject) => {
console.log("Pizza ordered. It will be ready soon.");
setTimeout(() => {
const isSuccess = true; // Simulate success or failure
if (isSuccess) {
resolve("Your pizza is ready!");
} else {
reject("Failed to make pizza.");
}
}, 2000); // Simulates a 2-second pizza preparation time
});
}
orderPizza()
.then(message => {
console.log(message);
})
.catch(error => {
console.error(error);
});

Benefits of Promises

- Avoid Callback Hell: Promises can chain operations with `.then()`.

- Better Error Handling: Promises have built-in error handling with `.catch()`.

Async/Await

Basics:

Async/Await is syntax that makes working with promises easier. `async` functions return a promise, and `await` makes JavaScript wait until the promise settles.

Get Amit Mishra’s stories in your inbox

Join Medium for free to get updates from this writer.

Example:

Async/await lets you handle promises in a more readable, synchronous-looking manner.

function orderPizza() {
return new Promise((resolve, reject) => {
console.log("Pizza ordered. It will be ready soon.");
setTimeout(() => {
const isSuccess = true; // Simulate success or failure
if (isSuccess) {
resolve("Your pizza is ready!");
} else {
reject("Failed to make pizza.");
}
}, 2000); // Simulates a 2-second pizza preparation time
});
}
async function notifyUser() {
try {
const message = await orderPizza();
console.log(message);
} catch (error) {
console.error(error);
}
}
notifyUser();

Benefits of Async/Await

- Readable Code: Looks like synchronous code, making it easier to read and write.

- Error Handling: Uses `try…catch` blocks, making error handling straightforward.

Comparison

1. Readability:

- Callbacks: Can become messy and hard to read with multiple nested callbacks.

- Promises: More readable than callbacks, especially with chaining.

- Async/Await: Most readable and looks like synchronous code.

2. Error Handling:

- Callbacks: Error handling can be difficult and inconsistent.

- Promises: Built-in `.catch()` method for errors.

- Async/Await: Uses `try…catch`, making it easy and consistent.

3. Complexity:

- Callbacks: Simple for small tasks but complicated for multiple async tasks.

- Promises: Handles multiple async tasks better but can still be complex with many `.then()` chains.

- Async/Await: Simplifies complex async code and handles multiple tasks elegantly.

Conclusion

Understanding how to handle asynchronous operations is crucial in JavaScript.

- Callbacks are the simplest form but can become cumbersome with nested tasks.

- Promises provide a cleaner way to handle async operations and manage errors.

- Async/Await offers the cleanest and most readable syntax, making your code look like synchronous code.

By mastering these three techniques, you’ll be well-equipped to handle any asynchronous task in JavaScript.!

--

--

Dev Genius
Dev Genius

Coding, Tutorials, News, UX, UI and much more related to development