Skip to main content

Implement a Custom Promisify Function

You are required to implement custom Promisify function.

Promisification is the process of converting a callback-based function into a function that returns a Promise object. Promises offer a more structured and readable way to manage asynchronous code compared to callback hell.

Promisify in Node.js

Node.js provides the util.promisify function specifically for this purpose.

const { promisify } = require('util');

const fs = require('fs');
const readFilePromisified = promisify(fs.readFile);

readFilePromisified('myfile.txt')
.then(data => console.log(data.toString()))
.catch(err => console.error(err));

Idea

To implement promisify, define a function that takes a callback-based function as an argument and returns a new function accepting any number of arguments.

This new function creates and returns a Promise, which invokes the original function with the provided arguments and a callback that resolves the promise on success and rejects it on error.

Algorithm

The solution based on 5 steps algorithm. Let's dive deep into each of them

  1. Function Definition. Define a function named promisify that takes a function (fn) as an argument.

function promisify(fn) {
// ...
}

  1. Return a New Function. Inside promisify, return a new function that can accept any number of arguments.
function promisify(fn) {
return function(...args) {
// ...
};
}

  1. Create a Promise. Within the new function, create and return a Promise with a two provided callbacks functions to handle its resolution or rejection: resolve and reject.
function promisify(fn) {
return function(...args) {
return new Promise((resolve, reject) => {
// ... (handle callback arguments)
});
};
}
  1. Invoke the Original Function. Inside the Promise, invoke the original function (fn) with the provided arguments, followed by a callback function.
function promisify(fn) {
return function(...args) {
return new Promise((resolve, reject) => {
fn(...args, (error, result) => {
// ...
});
});
};
}
  1. Handle the Callbacks. The callback function should handle the two possible outcomes. If there’s an error (err), reject the promise with the error. If there’s no error, resolve the promise with the result.
function promisify(fn) {
return function(...args) {
return new Promise((resolve, reject) => {
fn(...args, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
};
}

Code

Let's put it all together:

// Callback based function
function fetchData(callback) {
setTimeout(() => {
const data = { id: 1, name: 'Sample Data' };
callback(null, data);
}, 1000);
}

// Promisify function
function promisify(fn) {
return function(...args) {
return new Promise((resolve, reject) => {
fn(...args, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
};
}

// Example of usage
const fetchDataPromise = promisify(fetchData);
fetchDataPromise()
.then(data => {
console.log('Data received:', data);
})
.catch(error => {
console.error('Error fetching data:', error);
});

Summary

  • Promisification is the process of converting a function that relies on callbacks for handling asynchronous operations into a function that returns a Promise object.
  • Node.js has built-in util.promisify function

References