Nodeify: Promise to Node Callback Converter

raw JSON →
1.0.1 verified Thu Apr 23 auth: no javascript abandoned

Nodeify is a compact utility designed to convert Promise/A+-compliant promises into Node.js-style callback invocations. It allows developers to seamlessly integrate promise-based asynchronous operations into existing callback-driven codebases. The package offers several usage patterns: a direct functional approach, a `nodeify.Promise` constructor that returns promises with a `.nodeify` method, and various `extend` methods to add the `.nodeify` method to existing promise constructors or instances. The current stable version is 1.0.1. Due to its last publish date over seven years ago and no recent activity, the package is considered abandoned. For modern Node.js development, built-in features like `util.promisify` or native `async/await` are the preferred and more robust solutions for handling asynchronous operations and bridging between promises and callbacks.

error TypeError: callback is not a function
cause The second argument passed to `nodeify` was not a function, or the `this` context for `.nodeify()` method was incorrect.
fix
Ensure the second argument to nodeify (or the first to the .nodeify() method) is a valid function with the signature (err, result) => {...}.
error UnhandledPromiseRejectionWarning: (in some promise message) / Uncaught (in promise) (Error: ...)
cause A promise being 'nodeified' rejected, but no callback was provided, and no `.catch()` handler was attached to the returned promise.
fix
Either provide a callback function to nodeify to handle errors, or explicitly add a .catch() block to the promise returned by nodeify when no callback is used: nodeify(myPromise(), null).catch(err => console.error(err));
breaking This package is effectively abandoned. The last publish was over seven years ago, and there is no ongoing maintenance. While it may still function for its intended purpose, it is not recommended for new projects or for critical systems due to potential unaddressed issues or lack of compatibility with future Node.js versions.
fix For new projects, prefer native `async/await` syntax for promise management or `util.promisify` for converting callback-based APIs to promises. For existing promise-callback bridging, consider modern alternatives or maintaining the current version with caution.
gotcha Nodeify predates native ESM support in Node.js. It is primarily a CommonJS module. Direct `import` statements might require a transpiler (e.g., Babel) or specific Node.js loader configurations for older Node.js versions.
fix Use `const nodeify = require('nodeify');` for CommonJS projects. In ESM projects, consider a modern alternative or ensure proper build tool configuration to handle CommonJS modules.
gotcha If no callback function is provided to `nodeify`, it will simply return the original promise. If that promise rejects, and there are no `.catch()` handlers attached, an unhandled promise rejection might occur, potentially crashing the application in Node.js.
fix Always ensure that promises are handled either by providing a callback to `nodeify` or by explicitly chaining `.catch()` to the returned promise if no callback is supplied. For uncaught rejections, consider setting up a global `unhandledRejection` handler in Node.js.
gotcha The `nodeify.extend()` methods modify the prototype of a `PromiseConstructor` or a `Promise` instance. This global modification can lead to unexpected side effects or conflicts if multiple libraries attempt similar modifications or if the promise constructor is not the one `nodeify` expects.
fix Use the functional `nodeify(promise, callback)` approach or the `nodeify.Promise` constructor to avoid modifying global or shared Promise prototypes. If extending is necessary, ensure careful testing and isolation to prevent conflicts.
npm install nodeify
yarn add nodeify
pnpm add nodeify

Demonstrates `nodeify` converting a promise-based function to one that supports a Node.js-style callback, returning the promise if no callback is provided.

import nodeify from 'nodeify';

// Simulate an async operation that returns a Promise
function myPromiseMethod(arg) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (arg > 0) {
        resolve(`Processed: ${arg}`);
      } else {
        reject(new Error('Argument must be positive'));
      }
    }, 100);
  });
}

// Example 1: Using nodeify with a callback
function myAsyncMethodWithCallback(arg, callback) {
  return nodeify(myPromiseMethod(arg), callback);
}

myAsyncMethodWithCallback(5, (err, result) => {
  if (err) {
    console.error('Callback Error:', err.message);
  } else {
    console.log('Callback Result:', result);
  }
});

myAsyncMethodWithCallback(-1, (err, result) => {
  if (err) {
    console.error('Callback Error (negative arg):', err.message);
  } else {
    console.log('Callback Result (negative arg):', result);
  }
});

// Example 2: Using nodeify without a callback returns the original promise
const promiseOnly = myAsyncMethodWithCallback(10);
promiseOnly.then(res => console.log('Promise-only Result:', res)).catch(err => console.error('Promise-only Error:', err.message));