Back to results for “Async Patterns”
Node.js › Async Patterns

How do you convert a Node.js callback-based function into a Promise-based one manually, without using util.promisify()?

Beginner

Answer

You wrap the callback-based call inside 'new Promise((resolve, reject) => {...})', calling resolve() with the successful result inside the callback, or reject() with the error if the callback's first (error-first) argument is truthy -- this is exactly the pattern util.promisify() automates, but writing it manually is useful when the function doesn't follow the standard error-first convention or needs custom handling.
function readFilePromise(path) {
  return new Promise((resolve, reject) => {
    fs.readFile(path, 'utf-8', (err, data) => {
      if (err) reject(err);
      else resolve(data);
    });
  });
}

const content = await readFilePromise('config.json');
Real-world example A team integrating with a legacy internal SDK that uses a non-standard callback signature (success, data, error instead of error-first) manually wraps each needed method in a Promise constructor, since util.promisify() can't correctly handle that non-standard callback order automatically.

Common follow-ups: What happens if both resolve() and reject() are accidentally called inside the same Promise executor?;How would you add a timeout to a manually wrapped Promise so it doesn't hang forever if the callback is never invoked?