UNPKG

3.79 kBMarkdownView Raw
1# promise-callbacks
2
3This package helps you work with a codebase that uses promises vs. callbacks in most-but-not-all
4places. _It differs from all the other callback-to-promise libraries out there_ by not providing any sort of ["promisify[All]"](http://bluebirdjs.com/docs/api/promisification.html) APIs to convert
5and/or patch callback-using APIs to become promise-returning APIs. Rather, this function makes it
6easy to convert APIs to/from promises _at the call site_.
7
8It also uses native promises not Bluebird etc.
9
10This is because it's 2017, and this package assumes that you'll convert all your own code to use
11native promises (especially now that recent versions of Chrome and Node 7.6.0 natively support `
12async`/`await`) and the API calls left over will be 3rd-party libraries that you really don't want
13to patch, due to not having access to library classes and/or the general hackiness of
14monkey-patching ([trace this](https://github.com/petkaantonov/bluebird/blob/3746b7eca90dd8b11af73db5d30cf46d7dd90f9b/src/promisify.js#L295)).
15
16Hopefully these 3rd-party libraries will get [their](https://github.com/nodejs/node/pull/5020)
17[acts](https://github.com/request/request/issues/1935#issuecomment-287660358)
18[together](https://github.com/mafintosh/mongojs/issues/324#issuecomment-287591550)
19in the relatively near future. In the future, there's `promise-callbacks` to keep it simple.
20
21## Installation
22
23```sh
24npm install promise-callbacks --save
25```
26
27The minimum requirement is a native `Promise` implementation, though you'll get the most out of
28this if you're using Chrome minus 2 or Node 7.6.0 or higher for `async`/`await`.
29
30## Usage
31
32### Converting a callback to a promise
33
34```js
35const { sync } = require('promise-callbacks');
36
37function respondWithDelay(done) {
38 setTimeout(() => done(null, 'hi'), 2000);
39}
40
41async function foo() {
42 console.log(await sync.get(respondWithDelay(sync.set())));
43}
44```
45
46What happened there is that `sync.set()` stored a promise and returned a Node errback, which when
47called resolved that promise. `sync.get() retrieved the promise so that you could `await` it.
48
49`sync.get` doesn't take any arguments—putting the call to `respondWithDelay` "inside" it
50is just syntax sugar that works because JS interpreters evaluate the arguments to functions
51(i.e. `respondWithDelay(sync.set()))`) before the function calls themselves (`sync.get()`). It
52would be equivalent to do
53
54```js
55async function foo() {
56 respondWithDelay(sync.set());
57 console.log(await sync.get());
58}
59```
60
61The calls MUST be paired, i.e.:
62
631. Make sure you call `set` before `get`
642. Make sure to call `get` before calling `set` again
65
66The library will helpfully throw exceptions if you violate those guidelines.
67
68## Converting a promise to a callback
69
70```js
71const { asCallback } = require('promise-callbacks');
72
73asCallback(Promise.resolve(true), (err, res) => {
74 console.log(res); // true
75});
76```
77
78Straightforward. Or, if you don't mind just a little bit of monkey-patching:
79
80```js
81const { patchPromise } = require('promise-callbacks');
82
83// Call this once, when your application starts up,
84// to add `asCallback` to `Promise.prototype`.
85patchPromise();
86
87// Thereafter:
88Promise.resolve(true).asCallback((err, res) => {
89 console.log(res); // true
90});
91```
92
93## Real-world example
94
95`example/app.js` demonstrate these APIs' use in the context of a web server. Do `npm run example`
96to start it.
97
98## Shout-outs
99
100`sync` is inspired by / named after [`synchronize.js`](http://alexeypetrushin.github.io/synchronize/docs/index.html), a wonderful library that was Mixmax's [coroutine of choice](https://mixmax.com/blog/node-fibers-using-synchronize-js)
101prior to Node adding support for `async`/`await`.
102
103`asCallback` is inspired by [Bluebird](http://bluebirdjs.com/docs/api/ascallback.html).