{"_id":"deferential","_rev":"3-1b2b22a067b2eff5301544f207a7490f","name":"deferential","description":"es6 Native Promise Defer that helps build promise/callback dual APIS","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"deferential","version":"1.0.0","description":"es6 Native Promise Defer that helps build promise/callback dual APIS","main":"index.js","scripts":{"test":"mocha"},"repository":{"type":"git","url":"git+https://github.com/eugeneware/deferential.git"},"keywords":["promise","promises","defer","deferred","callback","nodeback","cb"],"author":{"name":"Eugene Ware","email":"eugene@noblesamurai.com"},"license":"BSD-3-Clause","bugs":{"url":"https://github.com/eugeneware/deferential/issues"},"dependencies":{"native-promise-only":"^0.8.1"},"devDependencies":{"expect.js":"~0.3.0","mocha":"~2.1.0"},"gitHead":"03146a365604945cdc07f4ca3ee5f240807d4f3a","homepage":"https://github.com/eugeneware/deferential#readme","_id":"deferential@1.0.0","_shasum":"f481c95e2b61a121c8aab9d6b41f78e04544097d","_from":".","_npmVersion":"3.4.0","_nodeVersion":"0.12.7","_npmUser":{"name":"eugeneware","email":"eugene@noblesamurai.com"},"maintainers":[{"name":"eugeneware","email":"eugene@noblesamurai.com"}],"dist":{"shasum":"f481c95e2b61a121c8aab9d6b41f78e04544097d","tarball":"https://registry.npmjs.org/deferential/-/deferential-1.0.0.tgz","integrity":"sha512-QyFNvptDP8bypD6WK6ZOXFSBHN6CFLZmQ59QyvRGDvN9+DoX01mxw28QrJwSVPrrwnMWqHgTRiXybH6Y0cBbWw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBbbQBVXqijVU7o6q3+8DQ+vF4qSvb6hSRIdhD9wUnrLAiB4DDjnog3s60W01fi4OH+P/uoeBJPeG4Il5g4wK1n1Rw=="}]}}},"readme":"# deferential\n\nes6 Native Promise Defer that helps build promise/callback dual APIS\n\n[![build status](https://secure.travis-ci.org/eugeneware/deferential.png)](http://travis-ci.org/eugeneware/deferential)\n\n## Installation\n\nThis module is installed via npm:\n\n``` bash\n$ npm install deferential\n```\n\n## Background\n\nIt is very easy to produce APIs that are equally consumable with node callbacks\nas *well* as promises.\n\nVarious promise libraries such as\n[Q](https://github.com/kriskowal/q/wiki/API-Reference#deferredmakenoderesolver)\nand [bluebird](http://bluebirdjs.com/docs/api/ascallback.html) have methods\nto either convert Promises or Deferred objects into forms that make it easy to\nadapt existing node.js APIS to support these *DUAL* APIs.\n\nHowever, as of ES6 (and node 0.12), Promises are native in Javascript, and thus\nthe need to have a heavy kitchen-sink API like Q or Bluebird is no longer\nnecessary as we get fast native-only implementations of Promises.\n\nAnd we can easily polyfill these with great libries such as\n[native-promise-only](https://github.com/getify/native-promise-only).\n\nThus, we can create some small focused, modules to add these additional\nfeatures that should work with any native Promise implementation.\n\n## Making a dual API function\n\nSay you have a regular function tht returns the contents of a file.\n\nHere is the callback version:\n\n``` js\nvar fs = require('fs');\n\nfunction getFile(fileName, cb) {\n  fs.readFile(fileName, 'utf8', cb);\n}\n\ngetFile('myfile.text', function (err, data) {\n  if (err) return console.error(err);\n  console.log(data);\n});\n```\n\nHere is the promise version:\n\n``` js\nvar Promise = require('native-promise-only'),\n    fs = require('fs');\n\nfunction getFile(fileName, cb) {\n  var p = new Promise(function (resolve, reject) {\n    fs.readFile(fileName, 'utf8', function (err, data) {\n      if (err) return reject(err);\n      resolve(data);\n    });\n  });\n  return p;\n}\n\ngetFile('myfile.txt')\n  .then(function (data) {\n    console.log(data);\n  })\n  .catch(function (err) {\n    console.error(err);\n  });\n```\n\nHere is a version that supports both!\n\n``` js\nvar Promise = require('native-promise-only'),\n    fs = require('fs'),\n    Deferred = require('deferential');\n\nfunction getFile(fileName, cb) {\n  var d = Deferred();\n  fs.readFile(fileName, 'utf8', d.resolver());\n  return d.nodeify(cb);\n}\n\n// Use with callback\ngetFile('myfile.text', function (err, data) {\n  if (err) return console.error(err);\n  console.log(data);\n});\n\n// Use with promise\ngetFile('myfile.txt')\n  .then(function (data) {\n    console.log(data);\n  })\n  .catch(function (err) {\n    console.error(err);\n  });\n```\n\nThe first line creats a new `Deferred` object:\n\n``` js\nvar d = Deferred();\n```\n\nThe `d.resolver()` returns a callback `thunk` which a standard node.js\ncallback function can call, and then depending on the error state, it will\n`resolve()` or `reject()` the underlying promise (represented as `d.promise`).\n\nThe last line detects whether a `cb` callback arguments was passed in, and if\nit is, it will callback the supplied `cb` based on the success or failure of the\nunderlying promise:\n\n``` js\nreturn d.nodeify(cb);\n```\n\nIf the `cb` argument is missing (ie. `undefined`) then `d.nodeify()` returns\nthe underlying promise so that the function can be used as a regular promise\nand chained with `.then()` and `.catch()` calls.\n\nSo, in summary, if a `cb` parameter is passed in `d.nodeify()` will call the\ncallback as normal and all is good to use the function as a regular callback.\n\nIf the `cb` parameter is missing, then a promise is returned.\n\nThe `Deferred` object has `resolve()` and `reject()` methods on it to help\nresolve/reject the state of the underlying `Promise`. But there is also a helper\nmethod called `Deferred#resolver()` which returns a `thunk` that can easily\npassed into the callback paramter of regular node.js functions to automate\nthe tedious `if (err) return d.reject(err)` logic.\n\n## API\n\n### `Deferred()`\n\nCreates a new instance of a Deferred. It can be created with or without the\n`new` operator.\n\n### `Deferred#resolve(value)`\n\nResolve the underlying `Promise`.\n\n### `Deferred#reject(err)`\n\nReject the underlying `Promise` with an error.\n\n### `Deferred#promise`\n\nReturn the underlying `Promise`. NB: This is a Native Promise as the underlying\nlibrary uses [native-promise-only](https://github.com/getify/native-promise-only)\nwhich will use the underlying Native `Promise` implementation or a native\npolyfill without all the guff.\n\n### `Deferred#resolver()`\n\nReturns a node.js `thunk` (a function with the signature `cb(err, results)`.\n\nPass this to a node.js style callback and then based on the result of the\ncallback, the undelrying `Promise` will be resolved/rejected.\n\n### `Deferred#nodeify(cb, [opts])`\n\nCall the provided `cb` node.js callback function if the underlying promise\nis resolved/rejected. If not, return the underlying promise to allow for\nregular `Promise` thenable chaining.\n\n* `cb` - node callback that will be called when the underlying `Deferred#promise`\n  is resolved/rejected.\n* `opts`:\n  * `spread` - (default: `false`). When `true` when multiple return arguments\n    are provided by the `#resolver()`, they will be mapped to additional\n    return arguments in the callback. This is because `Promises` can only\n    return a single value, whereas node.js callbacks can return multiple\n    return values (eg. `cb(null, val1, val2)`. If this is `false` and\n    multiple return values are returned, then the multiple values will\n    be returned as a single array of the return values. See the tests for\n    more details.\n","maintainers":[{"name":"eugeneware","email":"eugene@noblesamurai.com"}],"time":{"modified":"2022-06-14T23:22:49.353Z","created":"2016-01-02T08:20:28.646Z","1.0.0":"2016-01-02T08:20:28.646Z"},"homepage":"https://github.com/eugeneware/deferential#readme","keywords":["promise","promises","defer","deferred","callback","nodeback","cb"],"repository":{"type":"git","url":"git+https://github.com/eugeneware/deferential.git"},"author":{"name":"Eugene Ware","email":"eugene@noblesamurai.com"},"bugs":{"url":"https://github.com/eugeneware/deferential/issues"},"license":"BSD-3-Clause","readmeFilename":"README.md"}