Promisify a callback API
Plenty of libraries still take a callback as their last argument and call it with (error, value). Mixing that style with async/await is painful, so the usual fix is a small adapter written once.
Implement promisify(fn). It returns a new function that takes the same arguments as fn minus the trailing callback, and returns a Promise. Call fn with those arguments plus a callback of your own. When that callback receives a truthy first argument, reject with it. Otherwise resolve with the second argument, which may be undefined if the callback was called with only the error slot.
Arguments
fnFunction- A function whose last argument is an error-first callback
(error, value).
Returns
Function — A function that forwards its arguments to fn and returns a Promise resolving with the callback value or rejecting with the callback error.
Examples
const readValue = (key, cb) => setTimeout(() => cb(null, "v:" + key), 5);
const read = promisify(readValue);
const value = await read("theme");
// value === "v:theme"Call the wrapper like the original, minus the callback.
const failing = promisify((cb) => cb(new Error("disk offline")));
try {
await failing();
} catch (error) {
// error.message === "disk offline"
}A truthy first callback argument becomes a rejection.
What it has to do
- The returned function always returns a
Promise. - Forward every argument it is given to
fn, in order, before the callback. - Resolve with the callback's second argument when the first is falsy.
- Reject with the callback's first argument when it is truthy.
Notes
- Pass
thisthrough withfn.call(this, ...)so the wrapped function still works when used as a method. - Node's
util.promisifyhas quirks for legacy APIs likefs.exists; this version only handles the standard(error, value)shape.
Stuck? The javascript course covers everything this challenge needs.
- 1.resolves with the callback value
- 2.forwards every argument before the callback
- 3.rejects when the callback receives an error
- 4.resolves with undefined when only a null error is passed
- 5.returns a Promise every time
These assertions run in your browser the moment you hit Run. Pass all of them to claim the XP.
Discussion
Sign in to postNo comments yet. Be the first to say something.