Promisify a callback-based function using any-promise with support for multiple callback arguments and backward compatibility
npx @tessl/cli install tessl/npm-thenify@3.3.0Thenify is a Node.js library that converts callback-based functions into Promise-based functions using any-promise. It preserves function names, handles multiple callback arguments, supports both callback and promise styles, and ensures optimal performance by avoiding function deoptimization.
npm install thenifyconst thenify = require('thenify');Note: This package uses CommonJS and does not support ESM imports.
const thenify = require('thenify');
// Convert a callback-based function to promise-based
const somethingAsync = thenify(function somethingAsync(a, b, c, callback) {
callback(null, a, b, c);
});
// Use as promise
somethingAsync(1, 2, 3).then(function(result) {
console.log(result); // [1, 2, 3]
});
// Backward compatible version that supports both callbacks and promises
const backwardCompatible = thenify.withCallback(function(callback) {
callback(null, 'success');
});
// Both styles work:
backwardCompatible().then(result => console.log(result)); // 'success'
backwardCompatible(function(err, result) { console.log(result); }); // 'success'Converts callback-based functions to promise-based functions.
/**
* Promisifies a callback-based function
* @param {Function} fn - The callback-based function to promisify
* @param {Object} [options] - Configuration options
* @returns {Function} Promisified function that returns a Promise
*/
function thenify(fn, options);Usage Examples:
const thenify = require('thenify');
// Basic promisification
const readFileAsync = thenify(require('fs').readFile);
readFileAsync('file.txt').then(data => console.log(data));
// Function with multiple arguments becomes array
const multiArg = thenify(function(callback) {
callback(null, 1, 2, 3);
});
multiArg().then(result => console.log(result)); // [1, 2, 3]Promisifies a function while maintaining backward compatibility with callback style.
/**
* Promisifies a function with backward compatibility for callback style
* @param {Function} fn - The callback-based function to promisify
* @param {Object} [options] - Configuration options
* @returns {Function} Function that supports both promise and callback styles
*/
thenify.withCallback(fn, options);Usage Examples:
const thenify = require('thenify');
// Using the method directly
const flexible = thenify.withCallback(function(callback) {
callback(null, 'result');
});
// Promise style
flexible().then(result => console.log(result));
// Callback style
flexible(function(err, result) {
console.log(result);
});
// Alternative import pattern
const withCallback = require('thenify').withCallback;
const anotherFunction = withCallback(someCallbackFunction);Controls whether the resulting function supports both callback and promise styles.
Usage:
const hybrid = thenify(someFunction, { withCallback: true });
// Same as: thenify.withCallback(someFunction)Controls how multiple callback arguments are handled.
Usage Examples:
// Default behavior - multiple args become array
const defaultBehavior = thenify(function(callback) {
callback(null, 1, 2, 3);
});
defaultBehavior().then(result => console.log(result)); // [1, 2, 3]
// First argument only
const firstOnly = thenify(function(callback) {
callback(null, 1, 2, 3);
}, { multiArgs: false });
firstOnly().then(result => console.log(result)); // 1
// Object mapping
const objectMapping = thenify(function(callback) {
callback(null, 1, 2, 3);
}, { multiArgs: ['one', 'two', 'three'] });
objectMapping().then(result => console.log(result)); // { one: 1, two: 2, three: 3 }Thenify preserves the original function name in the promisified version:
function mySpecialFunction(callback) {
callback(null, 'done');
}
const promisified = thenify(mySpecialFunction);
console.log(promisified.name); // 'mySpecialFunction'Callback errors are automatically converted to promise rejections:
const errorFunction = thenify(function(callback) {
callback(new Error('Something went wrong'));
});
errorFunction().catch(err => console.log(err.message)); // 'Something went wrong'Thrown errors in the original function are also caught:
const throwingFunction = thenify(function(callback) {
throw new Error('Sync error');
});
throwingFunction().catch(err => console.log(err.message)); // 'Sync error'Thenify is designed to avoid function deoptimization and maintains optimal performance characteristics while providing the promisification functionality.
/**
* Options object for thenify functions
* @typedef {Object} ThenifyOptions
* @property {boolean} [withCallback] - Enable backward compatibility with callback style
* @property {boolean|string[]} [multiArgs] - Control behavior for multiple callback arguments:
* - true: converts to array (default)
* - false: use only first argument
* - Array: convert to object with provided keys
*/
/**
* Main thenify function - converts callback-based functions to promise-based
* @param {Function} fn - The callback-based function to promisify
* @param {ThenifyOptions} [options] - Configuration options
* @returns {Function} Promisified function that returns a Promise
*/
function thenify(fn, options);
/**
* Backward compatible version - supports both callback and promise styles
* @param {Function} fn - The callback-based function to promisify
* @param {ThenifyOptions} [options] - Configuration options
* @returns {Function} Function that supports both promise and callback styles
*/
thenify.withCallback(fn, options);