JavaScript How to Convert Callback to Promise Easily
Promise by calling resolve on success and reject on error, like new Promise((resolve, reject) => { callbackFunc((err, result) => { if (err) reject(err); else resolve(result); }); }).Examples
How to Think About It
Algorithm
Code
function callbackToPromise(callbackFunc) { return new Promise((resolve, reject) => { callbackFunc((err, result) => { if (err) reject(err); else resolve(result); }); }); } // Example callback function function exampleCallback(cb) { setTimeout(() => cb(null, 'Done!'), 1000); } callbackToPromise(exampleCallback).then(console.log).catch(console.error);
Dry Run
Let's trace exampleCallback through callbackToPromise
Call callbackToPromise
callbackToPromise(exampleCallback) creates a new Promise
Inside Promise, call exampleCallback
exampleCallback runs and waits 1 second
Callback fires with (null, 'Done!')
No error, so resolve('Done!') is called
| Step | Callback Arguments | Promise Action |
|---|---|---|
| 1 | N/A | Promise created |
| 2 | N/A | exampleCallback called |
| 3 | (null, 'Done!') | resolve('Done!') |
Why This Works
Step 1: Wrap callback in Promise
The Promise constructor lets you run asynchronous code and decide when to finish with resolve or reject.
Step 2: Handle callback results
Inside the callback, check if err exists. If yes, call reject(err) to signal failure.
Step 3: Resolve on success
If no error, call resolve(result) to pass the successful result to the Promise.
Alternative Approaches
const { promisify } = require('util'); const fs = require('fs'); const readFilePromise = promisify(fs.readFile); readFilePromise('file.txt', 'utf8').then(console.log).catch(console.error);
const fs = require('fs'); function readFilePromise(path) { return new Promise((resolve, reject) => { fs.readFile(path, 'utf8', (err, data) => { if (err) reject(err); else resolve(data); }); }); } readFilePromise('file.txt').then(console.log).catch(console.error);
Complexity: O(1) time, O(1) space
Time Complexity
Wrapping a callback in a Promise adds no loops or extra time complexity; it simply wraps the existing asynchronous call.
Space Complexity
The Promise wrapper uses constant extra space for the Promise object and callback closure.
Which Approach is Fastest?
Using util.promisify is efficient and clean for Node.js callbacks, while manual wrapping is flexible but slightly more verbose.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Manual Promise Wrapper | O(1) | O(1) | Any callback function |
| util.promisify (Node.js) | O(1) | O(1) | Node.js style callbacks |
| Legacy callback usage | O(1) | O(1) | Older code, no Promise support |
reject on errors and resolve on success inside the callback to properly convert it to a Promise.resolve causes the Promise to never reject on failure.