Skip to main content

Convert Callback Based Function to Promise Based Function - Solution & Explanation

MediumPremiumFree on FleetCode4 min read
Practice this problem

Problem Statement

Write a function that accepts another function fn and converts the callback-based function into a promise-based function. 

The function fn takes a callback as its first argument, along with any additional arguments args passed as separate inputs.

The promisify function returns a new function that should return a promise. The promise should resolve with the argument passed as the first parameter of the callback when the callback is invoked without error, and reject with the error when the callback is called with an error as the second argument.

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) => {
    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

Approach Overview

Problem Overview: You are given a function that follows the classic callback pattern where the last argument is a callback. The task is to create a wrapper that converts this function into a Promise-based version so callers can use async/await or .then() instead of callbacks.

Approach 1: Promise Wrapper Around Callback (O(1) time, O(1) space)

The simplest way is to return a new function that wraps the original function call inside a Promise. The wrapper collects all arguments using rest parameters (...args). When the wrapper runs, it creates a new Promise and calls the original function with the provided arguments plus a callback that resolves the promise. Once the callback executes, it passes the result to resolve, completing the asynchronous flow.

The key insight is that a Promise represents a future value. By resolving the Promise inside the callback, you bridge the old callback style with modern Promise-based control flow. This pattern is essentially a simplified version of Node's util.promisify. Time complexity is O(1) because the wrapper only performs a constant number of operations regardless of input size. Space complexity is also O(1), since it only allocates a single Promise and callback.

This approach is common when migrating legacy JavaScript APIs to modern asynchronous patterns. It works well with JavaScript runtime environments that rely heavily on callbacks. Once converted, the function becomes compatible with async programming patterns and integrates naturally with Promises and async/await.

Approach 2: Generic Promisify Wrapper with Error Handling (O(1) time, O(1) space)

Some callback APIs follow the Node.js error-first convention where the callback receives (error, result). A more defensive wrapper resolves when the result is returned and rejects when an error is provided. Inside the Promise executor, the wrapper injects a callback that checks whether the error argument is present. If so, it calls reject(error); otherwise it calls resolve(result).

This version is slightly more robust because it handles both success and failure paths. The operational complexity remains constant since it only performs a simple conditional check before resolving or rejecting the Promise.

Recommended for interviews: Interviewers typically expect the Promise wrapper approach. The critical signal is recognizing that you can inject a callback that triggers resolve. Demonstrating the Node-style error handling variant shows deeper understanding of real-world asynchronous APIs.

Solution

Code

TypeScript

Try this approach in the editor →

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Basic Promise WrapperO(1)O(1)When the callback simply returns a result without error handling
Error-First Promisify WrapperO(1)O(1)When converting Node.js-style callbacks that use (error, result)

Video Solution

Once You Realize This You Will Never Struggle With Callbacks Again • Web Dev Simplified • 366,885 views views

Watch 9 more video solutions →

Frequently Asked Questions

Is Convert Callback Based Function to Promise Based Function easy or hard?
The problem is typically rated Medium because it requires understanding higher-order functions, closures, and Promise mechanics. The implementation itself is short, but recognizing how to bridge callbacks with Promise resolution is the key insight.
Convert Callback Based Function to Promise Based Function Python/Java solution
This problem is designed around JavaScript's asynchronous callback pattern. In Python or Java, similar behavior is implemented using Futures, async/await constructs, or CompletableFuture in Java rather than direct callback-to-Promise conversion.
How to solve Convert Callback Based Function to Promise Based Function in O(1)?
Create a higher-order function that returns a new function. Inside that function, construct a Promise and call the original callback-based function with all arguments plus a callback that triggers resolve. Since the wrapper performs only constant work, the conversion operates in O(1) time and space.
What is the best approach for Convert Callback Based Function to Promise Based Function?
The best approach is wrapping the callback-based function inside a Promise and resolving the Promise inside the callback. This allows the function to work with async/await and .then() syntax. The wrapper runs in O(1) time and O(1) space since it only creates a single Promise and callback.
Is Convert Callback Based Function to Promise Based Function asked at Google/Amazon/Meta?
Callback-to-Promise conversion patterns frequently appear in JavaScript-focused interviews at companies building Node.js or frontend infrastructure. Variations of promisify-style questions test knowledge of asynchronous control flow and Promise mechanics.
What data structure is used in Convert Callback Based Function to Promise Based Function?
The solution primarily uses the JavaScript Promise object rather than a traditional data structure. The wrapper function leverages closures and rest parameters to forward arguments and resolve the Promise when the callback executes.
What is the time complexity of Convert Callback Based Function to Promise Based Function?
The conversion itself runs in O(1) time because the wrapper simply forwards arguments and attaches a callback that resolves the Promise. No loops or additional data structures are required. Space complexity is also O(1) due to the single Promise allocation.

Ready to solve this problem?

Practice Convert Callback Based Function to Promise Based Function with our built-in code editor and test cases.

Practice on FleetCode