Dev.to WebDev πŸ›  Dev πŸ‘ 1 πŸ“– 2 min read

Callback, Callback Hell & Promise in JavaScript

What is a Callback? A callback is simply a function passed as an argument to another function so that it can be executed later. Example: function greet(name) { console.log("Hello " + name); } function processU

What is a Callback?

A callback is simply a function passed as an argument to another function so that it can be executed later.

Example:

function greet(name) {
    console.log("Hello " + name);
}

function processUser(callback) {
    callback("Saravanan");
}

processUser(greet);

Output

Hello Saravanan

Here, greet is the callback function.

Why do we need callbacks?

Some tasks take time to complete.

For example:

  • Downloading data from a server
  • Reading a file
  • Waiting for a timer
  • Fetching API data

JavaScript doesn't stop the entire program while waiting.

Instead, it says:

"Continue doing other work. When this task finishes, I'll call the callback."

Example:

console.log("Start");

setTimeout(() => {
    console.log("Task Completed");
}, 2000);

console.log("End");

Output

Start
End
Task Completed

Notice that JavaScript didn't wait for 2 seconds before printing End.

The Problem: Callback Hell

Imagine we're building software using the SDLC process.

The order should be:

Planning
↓
Design
↓
Development
↓
Testing
↓
Deployment

Using callbacks:

function planning(callback) {
    setTimeout(() => {
        console.log("Planning Completed");
        callback();
    }, 1000);
}

function design(callback) {
    setTimeout(() => {
        console.log("Design Completed");
        callback();
    }, 1000);
}

function development(callback) {
    setTimeout(() => {
        console.log("Development Completed");
        callback();
    }, 1000);
}

function testing(callback) {
    setTimeout(() => {
        console.log("Testing Completed");
        callback();
    }, 1000);
}

function deploy() {
    console.log("Deployment Completed");
}

planning(() => {
    design(() => {
        development(() => {
            testing(() => {
                deploy();
            });
        });
    });
});

Although the program works, there's a problem.

The code keeps moving further to the right.

planning(
    design(
        development(
            testing(
                deploy()
            )
        )
    )
)

This deeply nested structure is called Callback Hell.

Problems with Callback Hell:

  • Difficult to read
  • Difficult to debug
  • Difficult to maintain
  • Becomes messy as the project grows

Solution: Promise

A Promise represents the result of an asynchronous operation.

It can be in one of three states:

  • Pending
  • Fulfilled (Resolved)
  • Rejected

Creating a Promise:

const planning = () => {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log("Planning Completed");
            resolve();
        }, 1000);
    });
};

The Promise either calls:

resolve();

when successful,

or

reject();

when something goes wrong.

Promise Chaining

Now we can execute tasks one after another without nesting.

planning()
    .then(() => design())
    .then(() => development())
    .then(() => testing())
    .then(() => deploy())
    .catch(() => console.log("Something went wrong."));

This code is much easier to read.

It clearly says:

Planning
β†’ Design
β†’ Development
β†’ Testing
β†’ Deploy

Even Cleaner: async/await

JavaScript introduced async and await to make Promise-based code look more like normal synchronous code.

async function SDLC() {
    try {
        await planning();
        await design();
        await development();
        await testing();
        await deploy();
    } catch (error) {
        console.log(error);
    }
}

SDLC();

This is usually easier to understand because the steps appear in the same order they execute.

Callback Hell vs Promise

Callback Hell Promise
Deeply nested code Flat and readable code
Hard to maintain Easy to maintain
Difficult error handling Centralized error handling using .catch()
Less readable as the project grows Easier to understand and extend

References:
https://www.w3schools.com/js/js_promise.asp
https://www.geeksforgeeks.org/javascript/javascript-promise/

πŸ“° Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.