Before promises/async/await became the standard, it was a convention for async APIs in JavaScript to accept callbacks as the last argument. Many async versions of Node.js APIs (e.g. fs.readFile and fs.rm) have such signatures. Node.js’ util.promisify function was created to wrap around callback-based functions by returning Promises so that they can be used with async/await.
Implement a function promisify that takes a function following the common callback-last error-first style, i.e. taking a (err, value) => ... callback as the last argument, and returns a version that returns promises.
// Example function with callback as last argument
// The callback has the signature `(err, value) => any`
function foo(url, options, callback) {
apiCall(url, options)
.then((data) => callback(null, data))
.catch((err) => callback(err));
}
const promisifiedFoo = promisify(foo);
const data = await promisifiedFoo('example.com', { foo: 1 });
Here’s a clear and simple explanation of the problem.
You must implement a function promisify, which converts a callback-based async function into a Promise-based version.
This lets old “callback-style” APIs be used with modern async/await.
Before Promises and async/await existed, Node.js used the error-first callback pattern:
callback(error, value);
Meaning:
If the operation fails, you call:
callback(err)
If the operation succeeds, you call:
callback(null, result)
Modern code prefers Promises and async/await, so we need to convert:
callback API → promise API