Wrap an error-first callback function so it returns a promise
Implement promisify(fn) that adapts a Node-style error-first-callback function into one that returns a promise. Requirements: the returned function forwards all arguments to fn, appends a callback (err, result); reject with err when present, otherwise resolve with result. Preserve the caller's this.
function promisify(fn) {
// your code here
}
Write the implementation.
Return a wrapper that builds a new Promise and calls fn.apply(this, [...args, cb]), where cb = (err, result) => err ? reject(err) : resolve(result). Using a regular function for the wrapper (not an arrow) and apply(this, …) keeps the original this, and appending the callback last matches the error-first convention.
- ✗Using an arrow function for the wrapper, which loses the caller's
this - ✗Forgetting to reject — silently swallowing the error-first
errargument - ✗Calling
fn(args)instead of appending the callback as the final argument
- →Why must the wrapper be a regular function rather than an arrow to keep
this? - →How would you handle a callback that yields multiple result arguments?
Solution
The wrapper builds a promise and supplies the error-first callback as the final argument.
function promisify(fn) {
return function (...args) {
return new Promise((resolve, reject) => {
fn.apply(this, [...args, (err, result) => {
if (err) reject(err);
else resolve(result);
}]);
});
};
}
How it works
The returned function is a regular function so it captures the call-site this, then forwards it into fn via apply. All original arguments pass through unchanged, and a (err, result) callback is appended last. The callback mirrors the error-first convention: a truthy err triggers reject, otherwise result flows into resolve. This lets any Node-style function be used with await.