1 | # promise-callbacks
|
2 |
|
3 | This package helps you work with a codebase that uses promises vs. callbacks in most-but-not-all
|
4 | places. _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
|
5 | and/or patch callback-using APIs to become promise-returning APIs. Rather, this function makes it
|
6 | easy to convert APIs to/from promises _at the call site_.
|
7 |
|
8 | It also uses native promises not Bluebird etc.
|
9 |
|
10 | This is because it's 2017, and this package assumes that you'll convert all your own code to use
|
11 | native promises (especially now that recent versions of Chrome and Node 7.6.0 natively support `
|
12 | async`/`await`) and the API calls left over will be 3rd-party libraries that you really don't want
|
13 | to patch, due to not having access to library classes and/or the general hackiness of
|
14 | monkey-patching ([trace this](https://github.com/petkaantonov/bluebird/blob/3746b7eca90dd8b11af73db5d30cf46d7dd90f9b/src/promisify.js#L295)).
|
15 |
|
16 | Hopefully 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)
|
19 | in the relatively near future. In the future, there's `promise-callbacks` to keep it simple.
|
20 |
|
21 | ## Installation
|
22 |
|
23 | ```sh
|
24 | npm install promise-callbacks --save
|
25 | ```
|
26 |
|
27 | The minimum requirement is a native `Promise` implementation, though you'll get the most out of
|
28 | this 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
|
35 | const { sync } = require('promise-callbacks');
|
36 |
|
37 | function respondWithDelay(done) {
|
38 | setTimeout(() => done(null, 'hi'), 2000);
|
39 | }
|
40 |
|
41 | async function foo() {
|
42 | console.log(await sync.get(respondWithDelay(sync.set())));
|
43 | }
|
44 | ```
|
45 |
|
46 | What happened there is that `sync.set()` stored a promise and returned a Node errback, which when
|
47 | called 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
|
50 | is 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
|
52 | would be equivalent to do
|
53 |
|
54 | ```js
|
55 | async function foo() {
|
56 | respondWithDelay(sync.set());
|
57 | console.log(await sync.get());
|
58 | }
|
59 | ```
|
60 |
|
61 | The calls MUST be paired, i.e.:
|
62 |
|
63 | 1. Make sure you call `set` before `get`
|
64 | 2. Make sure to call `get` before calling `set` again
|
65 |
|
66 | The library will helpfully throw exceptions if you violate those guidelines.
|
67 |
|
68 | ## Converting a promise to a callback
|
69 |
|
70 | ```js
|
71 | const { asCallback } = require('promise-callbacks');
|
72 |
|
73 | asCallback(Promise.resolve(true), (err, res) => {
|
74 | console.log(res); // true
|
75 | });
|
76 | ```
|
77 |
|
78 | Straightforward. Or, if you don't mind just a little bit of monkey-patching:
|
79 |
|
80 | ```js
|
81 | const { patchPromise } = require('promise-callbacks');
|
82 |
|
83 | // Call this once, when your application starts up,
|
84 | // to add `asCallback` to `Promise.prototype`.
|
85 | patchPromise();
|
86 |
|
87 | // Thereafter:
|
88 | Promise.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`
|
96 | to 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)
|
101 | prior to Node adding support for `async`/`await`.
|
102 |
|
103 | `asCallback` is inspired by [Bluebird](http://bluebirdjs.com/docs/api/ascallback.html).
|