Before async/await, half the Node ecosystem was error-first callbacks. promisify is the bridge: hand it a callback-style function and it gives you back a promise-returning version. The question tests whether you actually understand the callback convention, not just the syntax.
Node callbacks take the shape (error, result). If error is truthy, something went wrong; otherwise result holds the value. promisify maps that straight onto a promise: reject with the error, or resolve with the result.
function promisify(fn) {
return function (...args) {
return new Promise((resolve, reject) => {
fn.apply(this, [
...args,
(err, result) => {
if (err) reject(err);
else resolve(result);
},
]);
});
};
}fn.apply(this, ...), not fn(...). If the callback-style function is a method that relies on this, a plain call would break it. Using apply with this keeps method calls working.err rejects and you never touch result."What if the callback can return multiple results, like (err, a, b)?" Node's own util.promisify resolves with just the first result by default and ignores the rest. Mention that you'd resolve with an array if multiple values mattered, but the standard behavior is to take the single result. Knowing the real implementation's quirk is the senior signal here.
In the editor, get the success and error cases passing. Then try promisifying a method that uses this and confirm your apply actually preserves it — that's the detail most quick answers drop.
function promisify(fn) { // your code here } // Try it: function readValue(key, callback) { setTimeout(() => { if (key === "missing") callback(new Error("not found")); else callback(null, `value for ${key}`); }, 20); } const read = promisify(readValue); read("user").then(console.log); // "value for user"
Test Code
Enter JavaScript that runs after your solution. It should return a value or a Promise.