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
     */
    
    

All Problems

All Solutions