Welcome to Subscribe On Youtube
2776. Convert Callback Based Function to Promise Based Function
Description
Write a function that accepts another function fn
and converts the callback-based function into a promise-based function.
The promisify
function takes in a function fn
that accepts a callback as its first argument and also any additional arguments. It returns a new function that returns a promise instead. The returned promise should resolve with the result of the original function when the callback is called with a successful response, and reject with the error when the callback is called with an error. The returned promise-based function should accept the additional arguments as inputs.
The following is an example of a function that could be passed into promisify
.
function sum(callback, a, b) { if (a < 0 || b < 0) { const err = Error('a and b must be positive'); callback(undefined, err); } else { callback(a + b); } }
This is the equivalent code based on promises:
async function sum(a, b) { if (a < 0 || b < 0) { throw Error('a and b must be positive'); } else { return a + b; } }
Example 1:
Input: fn = (callback, a, b, c) => { return callback(a * b * c); } args = [1, 2, 3] Output: {"resolved": 6} Explanation: const asyncFunc = promisify(fn); asyncFunc(1, 2, 3).then(console.log); // 6 fn is called with a callback as the first argument and args as the rest. The promise based version of fn resolves a value of 6 when called with (1, 2, 3).
Example 2:
Input: fn = (callback, a, b, c) => { callback(a * b * c, "Promise Rejected"); } args = [4, 5, 6] Output: {"rejected": "Promise Rejected"} Explanation: const asyncFunc = promisify(fn); asyncFunc(4, 5, 6).catch(console.log); // "Promise Rejected" fn is called with a callback as the first argument and args as the rest. As the second argument, the callback accepts an error message, so when fn is called, the promise is rejected with a error message provided in the callback. Note that it did not matter what was passed as the first argument into the callback.
Constraints:
1 <= args.length <= 100
0 <= args[i] <= 104
Solutions
-
type CallbackFn = (next: (data: number, error: string) => void, ...args: number[]) => void; type Promisified = (...args: number[]) => Promise<number>; function promisify(fn: CallbackFn): Promisified { return async function (...args) { return new Promise((resolve, reject) => { fn((data, error) => { if (error) { reject(error); } else { resolve(data); } }, ...args); }); }; } /** * const asyncFunc = promisify(callback => callback(42)); * asyncFunc().then(console.log); // 42 */