The callback is a function that is passed as a parameter to another function. And this function will be called inside the function.
A promise is an object which is used to handle asynchronous operations. It is used to handle multiple asynchronous operations which may have a dependency on each other.
Callback and promise are used to handle asynchronous operations. An asynchronous operation is an operation that is not executed immediately. It is executed after some time. For example, if you are making a request to the server to get some data, then it will take some time to get a response from the server. So, we need to wait for the response. If we are making multiple requests to the server, then we need to wait for all the responses. So, we need to handle asynchronous operations.
We need to convert callback to promise because the promise is more readable and easier to handle. We can handle multiple asynchronous operations using promise. We can also handle asynchronous operations which have a dependency on each other using promise.
Let's understand this with an example.
Suppose we have a simple add function that will take two numbers and return the sum of those two numbers in a callback function. I've also added the setTimeout function to simulate the asynchronous behavior of the function.
Note: I'm creating a standard error first callback function. In the standard error first callback function, the first parameter is an error, and the second parameter results.
function add(a, b, callback) {
setTimeout(() => callback(null, a + b), 100);
}
add(1, 2, (err, sum) => {
console.log(sum);
});
This is a pretty simple function. We are getting the result after 100ms. Now, let's say we want to add another number to the result. We can do this by passing the result to another function.
add(1, 2, (err, first) => {
console.log(first);
add(first, 3, (err, second) => {
console.log(second);
add(second, 4, (err, finalResult) => {
console.log(finalResult);
});
});
});
If we use a callback function, then we need to write a nested callback function to handle asynchronous operations. This is not readable and it gets dipper and dipper as we add more asynchronous operations. This is also called callback hell.
Now we know the problem with a callback function. Let's see how we can solve this problem using promise.
We will create a promisify function that will take the callback function as a parameter and return the promise. There are many npm packages available that can be used to convert the callback function to promise. But, I will show you how to convert the callback function to promise without using any npm package. Node.js already provides a utility function called promisify which can be used to convert the callback function to promise.
const promisify =
(fn) =>
(...args) =>
new Promise((resolve, reject) => {
fn(...args, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
Let's see how it works.
function add(a, b, callback) {
setTimeout(() => callback(null, a + b), 100);
}
const addPromise = promisify(add);
const run = async () => {
const first = await addPromise(1, 2);
console.log(first);
const second = await addPromise(first, 3);
console.log(second);
const finalResult = await addPromise(second, 4);
console.log(finalResult);
};
This is much more readable and easy to handle. We can also handle multiple asynchronous operations which have a dependency on each other using promise.
If you are using node.js version 8 or above, then you can use util.promisify function to convert the callback function to promise.
const { promisify } = require("util");
const addPromise = promisify(add);
Thank you for reading 😊
Got any additional questions? please leave a comment.