
The Difference Between JavaScript Callbacks and Promises

In JavaScript, handling asynchronous operations effectively is very important when we're building modern applications. Two primary approaches for managing asynchronous behaviour are callbacks and promises. Whilst both aim to solve similar problems, they differ in structure, usability, and maintainability.
In this article, I intend to explore the key differences between callbacks and promises, their advantages, and when to use each. By the end, you should hopefully have a clear understanding of how to work with both techniques and choose the right tool for the task.
What are Callbacks?
A callback is a function passed as an argument to another function, which is then executed at a later time. Callbacks have been a foundational concept in JavaScript for handling asynchronous tasks like reading files, making HTTP requests, or responding to user interactions.
Example of a Callback
function fetchData(url: string, callback: (data: string) => void): void { setTimeout(() => { const data = `Data from ${url}`; callback(data); }, 1000);}fetchData("https://api.example.com", (data) => { console.log(data); // Output: Data from https://api.example.com});In this example:
- The
fetchDatafunction simulates an asynchronous operation usingsetTimeout. - The
callbackfunction is executed when the data is ready, allowing us to process it.
Downsides of Callbacks
Callback Hell
: Nesting multiple callbacks can result in deeply nested and hard‑to‑read code.Error Handling
: Managing errors across multiple callbacks is cumbersome and often inconsistent.
What are Promises?
A promise is a JavaScript object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. Promises offer a more structured and readable way to handle asynchronous tasks.
Example of a Promise
function fetchData(url: string): Promise<string> { return new Promise((resolve, reject) => { setTimeout(() => { const data = `Data from ${url}`; resolve(data); }, 1000); });}fetchData("https://api.example.com") .then((data) => { console.log(data); // Output: Data from https://api.example.com }) .catch((error) => { console.error("Error:", error); });In this example:
- The
fetchDatafunction returns aPromise. - The
thenmethod handles the resolved value, whilstcatchhandles errors, making the code more structured.
Advantages of Promises
Chaining
: Promises allow chaining multiple asynchronous operations using.then().Error Propagation
: Errors can be caught at any point in the chain with.catch(), providing a cleaner error‑handling mechanism.
Key Differences Between Callbacks and Promises
| Feature | Callbacks | Promises |
|---|---|---|
| Syntax | Function passed as an argument | Object with .then() and .catch() methods |
| Readability | Can lead to nested code (callback hell) | Cleaner and easier to follow with chaining |
| Error Handling | Must handle errors manually at each step | Centralised error handling with .catch() |
| Flexibility | Limited to specific callback patterns | Supports chaining and more complex flows |
When to Use Callbacks or Promises
Use Callbacks When:
- You're working with older APIs or libraries that don't support promises.
- The task is simple and doesn't require chaining or complex error handling.
Use Promises When:
- You're writing modern, maintainable code.
- The task involves multiple asynchronous steps that benefit from chaining.
- You want better error handling and improved readability.
Moving Forward: Async/await
Whilst callbacks and promises are both valid approaches, modern JavaScript developers often use async/await, a syntactic sugar built on top of promises to simplify asynchronous code further. For example:
async function fetchData(url: string): Promise<string> { return new Promise((resolve, reject) => { setTimeout(() => { const data = `Data from ${url}`; resolve(data); }, 1000); });}async function getData(): Promise<void> { try { const data = await fetchData("https://api.example.com"); console.log(data); // Output: Data from https://api.example.com } catch (error) { console.error("Error:", error); }}getData();This approach combines the benefits of promises with a synchronous style, which makes what might otherwise be relatively complex code all the easier to both read and maintain.
Wrapping up
Understanding the differences between callbacks and promises is essential for effectively handling asynchronous operations in JavaScript. Both approaches have their place, but promises (and, by extension, async/await) offer a more modern, readable, and maintainable solution for most scenarios.
Key Takeaways
- Callbacks are functions passed as arguments and executed later, but they can lead to callback hell and poor error handling.
- Promises provide a more structured approach with chaining and centralised error handling.
- Async/await builds on promises, simplifying asynchronous code further.
- Choose the right approach based on your project's requirements and complexity.
By mastering callbacks, promises, and async/await, you'll be well‑equipped to write robust and efficient asynchronous JavaScript.
Related Articles

Array.find(), Array.some(), and Array.every() in JavaScript. 
Simplify Asynchronous JavaScript with async/await. Simplify Asynchronous JavaScript with
async/await
Getting Started with Callbacks in JavaScript. Getting Started with Callbacks in JavaScript

Promises in JavaScript: An Introduction. Promises in JavaScript: An Introduction

Understanding the Composition API in Vue 3. Understanding the Composition API in Vue 3

How to Find a Programmer Job. How to Find a Programmer Job

Differences Between Falsy and Nullish Values in JavaScript. Differences Between Falsy and Nullish Values in JavaScript

What is a Static Site Generator? What is a Static Site Generator?

Optimising HTML Markup for SEO. Optimising HTML Markup for SEO

Dynamically Create a Script Element with JavaScript. Dynamically Create a Script Element with JavaScript

Unravelling JavaScript: Commonly Misunderstood Methods and Features. Unravelling JavaScript: Commonly Misunderstood Methods and Features

Some of the Most‑Misunderstood Properties in CSS. Some of the Most‑Misunderstood Properties in CSS