Socket
Socket
Sign inDemoInstall

promise-nodeify

Package Overview
Dependencies
0
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

promise-nodeify


Version published
Maintainers
1
Install size
35.2 kB
Created

Changelog

Source

v3.0.1 (2018-08-29)

Full Changelog

  • Update Babel-related devDependencies to the latest version
  • Remove unnecessary Babel build dependencies.
  • Update nodecat devDependency to the latest version 🚀 #24

Readme

Source

promise-nodeify

Build Status: Linux Build Status: Windows Coverage Dependency Status Supported Node Version Version on NPM

Call a Node-style callback with the resolution value or rejection cause of a Promise without the common pitfalls.

Introductory Example

var promiseNodeify = require('promise-nodeify');

// Function which returns a Promise
function returnsPromise() {
  return new Promise(function(resolve, reject) {
    resolve(42);
  });
}

// Function which takes an optional node-style callback
function takesCallback(callback) {
  var promise = returnsPromise();
  // if callback is not a function, promise is returned as-is
  // otherwise callback will be called when promise is resolved or rejected
  // promise will not cause unhandledRejection if callback is a function
  return promiseNodeify(promise, callback);
}

Features

The important features of nodeify as compared to naive implementations:

  • Creates Error for falsey rejection causes. Since Promises may resolve or reject without providing a value or cause, the callback would have no way to distinguish success from failure. This module ensures the error argument is always truthy, substituting an Error when the rejection cause is falsey (and passing the original value as the .cause property, as bluebird does).
  • Exceptions thrown by callback cause uncaughtException as they would for other callbacks (unlike passing callback to .then, which causes unhandledRejection or swallows them).
  • The callback handles the promise rejection, preventing unhandledRejection (unlike if the promise were ignored and callback invoked directly).
  • Reduces confusion by only returning a Promise when no callback is given (as opposed to returning the promise argument, which creates uncertainty about unhandledRejections and multiple threads of control - or returning the result passing the callback to .then, which resolves to the callback result).

Behavior Comparison

This module provides similar behavior to several popular promise libraries in a promise-library-agnostic way which only requires the ES6 promise functionality subset. However, these existing implementations differ in subtle ways. A brief comparison:

Behaviorthis modulebluebird #asCallbackes-nodeifynodeifythen #nodeifyUn-thenify1when.js .bindCallback
returns (with function)undefinedthis Promise2undefinedPromise<undefined>undefinedundefinedwhen(promise)
returns (with falsey)promisepromisepromisePromise<undefined>promiseundefined with unhandledRejectionwhen(promise)
returns (non-function)promisepromiseundefined with unhandledRejectionpromisepromiseundefined with unhandledRejectionwhen(promise) with uncaughtException
callback exceptionuncaughtExceptionuncaughtExceptionunhandledRejectionuncaughtExceptionuncaughtExceptionunhandledRejectionuncaughtException
falsey causeError with .causeError with .cause3Errorfalsey causefalsey causeTypeErrorfalsey cause
reject argument length1111112
resolve argument length2undefined ? 1 : 2422222
extra argumentignoredoptions5ignoredignoredthis of callbackignoredignored

Notes:

  1. Un-thenify serves a similar purpose, but wraps the Promise-returning function rather than taking the Promise as an argument.
  2. Temporarily reverted in https://github.com/petkaantonov/bluebird/issues/151 and restored in https://github.com/petkaantonov/bluebird/issues/168
  3. In response to https://github.com/petkaantonov/bluebird/issues/434
  4. In response to https://github.com/petkaantonov/bluebird/issues/170
  5. Supports the spread boolean option to pass Array values as separate arguments to callback.

Performance Comparison

These benchmarks were done using the benchmark/index.js script on an Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz with Node v4.3.1 on Linux and the following module versions:

ModuleVersion
benchmark2.1.0
bluebird3.3.3
cli-table0.3.1
es-nodeify1.0.0
microtime2.0.0
native-promise-only0.8.1
nodeify1.0.0
pinkie-promise2.0.0
promise7.1.1
q1.4.1
rsvp3.2.1
unthenify1.0.1
when3.7.7

Nodeify Resolved Promise

Performance (in operations per second) of calling nodeify on a resolved promise (larger is better):

ops/secbluebirdnativenpopinkieqrsvpthenwhen
bluebird#nodeify1,922,721.987TypeErrorTypeErrorTypeErrorTypeErrorTypeErrorTypeErrorTypeError
es-nodeify1,345,702.588506,103.345510,887.217534,013.96168,915.8161,974,250.7372,096,468.1191,756,177.934
nodeify147,481.019251,414.264251,535.145253,880.99858,504.0981,355,812.4821,102,467.7561,160,226.624
promiseNodeify1,586,092.279481,842.79452,529.247455,657.06266,045.2732,108,607.1262,370,823.7231,942,722.539
then#nodeify136,716.987202,670.23225,297.257231,042.28656,384.953764,719.551,320,158.92739,062.155
unthenify100,638.92279,097.9980,488.2578,298.36540,683.82103,125.162100,618.139101,887.997
when.bindCallback823.326856.669842.975834.864748.669847.556850.316839.995

Nodeify Rejected Promise

Performance (in operations per second) of calling nodeify on a rejected promise (larger is better):

ops/secbluebirdnativenpopinkieqrsvpthenwhen
bluebird#nodeify1,889,496.469TypeErrorTypeErrorTypeErrorTypeErrorTypeErrorTypeErrorTypeError
es-nodeify1,247,981.228520,349.959455,337.77466,964.69264,703.2472,182,281.0052,062,330.0351,889,184.935
nodeify147,454.87325,956.476326,958.556325,971.63753,878.0981,232,726.201952,338.091926,626.949
promiseNodeify1,170,756.604465,186.326478,343.59489,024.09462,905.8012,097,277.3711,928,682.9431,497,451.328
then#nodeify131,588.987241,627.02246,557.24245,427.55349,655.492684,232.8641,178,175.996634,041.464
unthenify96,359.91682,291.67982,507.05583,324.58438,842.74196,432.33297,113.0599,892.099
when.bindCallback822.083837.698848.358851.348789.546854.184844.102851.644

Installation

NPM

This package can be installed using npm by running:

npm install promise-nodeify

Browser

This package can be installed using bower by running:

bower install promise-nodeify

Without Package Manager

This module is also available with a UMD loader, both minified and un-minified, in the dist directory. They can be downloaded, self-hosted, or loaded from a CDN. To use the RawGit CDN, use the following (X)HTML:

<script src="https://cdn.rawgit.com/kevinoid/promise-nodeify/v0.1.0/dist/promise-nodeify.min.js"></script>

Recipes

Delegate to Promise.prototype.nodeify

If the behavior differences discussed in the Behavior Comparison section (and any future differences which may occur) are not significant to your use case and you are interested in taking advantage of the potential performance benefit of the implementation provided by the promise library, use the .delegated function:

// Using .delegated delegates to .nodeify on the promise argument when present
var promiseNodeify = require('promise-nodeify').delegated;

function returnsPromise() {
  return new Promise(function(resolve, reject) {
    resolve(42);
  });
}

function takesCallback(callback) {
  var promise = returnsPromise();
  return promiseNodeify(promise, callback);
}

Polyfill Promise.prototype.nodeify

To polyfill the .nodeify (or .asCallback) method for a Promise library, assign the .nodeifyThis function to Promise.prototype.nodeify as follows:

Promise.prototype.nodeify = require('promise-nodeify').nodeifyThis;

function returnsPromise() {
  return new Promise(function(resolve, reject) {
    resolve(42);
  });
}

function takesCallback(callback) {
  var promise = returnsPromise();
  return promise.nodeify(callback);
}

More examples can be found in the test specifications.

API Docs

For a description of the available functions and their arguments, see the API Documentation.

Contributing

Contributions are welcome and very much appreciated! Please add tests to cover any changes and ensure npm test passes.

The dist files are only updated for releases, so please don't include them in pull requests.

If the desired change is large, complex, backwards-incompatible, can have significantly differing implementations, or may not be in scope for this project, opening an issue before writing the code can avoid frustration and save a lot of time and effort.

License

This package is available under the terms of the MIT License.

Keywords

FAQs

Last updated on 29 Aug 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc