| 1 | ## Any Promise
|
|---|
| 2 |
|
|---|
| 3 | [](http://travis-ci.org/kevinbeaty/any-promise)
|
|---|
| 4 |
|
|---|
| 5 | Let your library support any ES 2015 (ES6) compatible `Promise` and leave the choice to application authors. The application can *optionally* register its preferred `Promise` implementation and it will be exported when requiring `any-promise` from library code.
|
|---|
| 6 |
|
|---|
| 7 | If no preference is registered, defaults to the global `Promise` for newer Node.js versions. The browser version defaults to the window `Promise`, so polyfill or register as necessary.
|
|---|
| 8 |
|
|---|
| 9 | ### Usage with global Promise:
|
|---|
| 10 |
|
|---|
| 11 | Assuming the global `Promise` is the desired implementation:
|
|---|
| 12 |
|
|---|
| 13 | ```bash
|
|---|
| 14 | # Install any libraries depending on any-promise
|
|---|
| 15 | $ npm install mz
|
|---|
| 16 | ```
|
|---|
| 17 |
|
|---|
| 18 | The installed libraries will use global Promise by default.
|
|---|
| 19 |
|
|---|
| 20 | ```js
|
|---|
| 21 | // in library
|
|---|
| 22 | var Promise = require('any-promise') // the global Promise
|
|---|
| 23 |
|
|---|
| 24 | function promiseReturningFunction(){
|
|---|
| 25 | return new Promise(function(resolve, reject){...})
|
|---|
| 26 | }
|
|---|
| 27 | ```
|
|---|
| 28 |
|
|---|
| 29 | ### Usage with registration:
|
|---|
| 30 |
|
|---|
| 31 | Assuming `bluebird` is the desired Promise implementation:
|
|---|
| 32 |
|
|---|
| 33 | ```bash
|
|---|
| 34 | # Install preferred promise library
|
|---|
| 35 | $ npm install bluebird
|
|---|
| 36 | # Install any-promise to allow registration
|
|---|
| 37 | $ npm install any-promise
|
|---|
| 38 | # Install any libraries you would like to use depending on any-promise
|
|---|
| 39 | $ npm install mz
|
|---|
| 40 | ```
|
|---|
| 41 |
|
|---|
| 42 | Register your preference in the application entry point before any other `require` of packages that load `any-promise`:
|
|---|
| 43 |
|
|---|
| 44 | ```javascript
|
|---|
| 45 | // top of application index.js or other entry point
|
|---|
| 46 | require('any-promise/register/bluebird')
|
|---|
| 47 |
|
|---|
| 48 | // -or- Equivalent to above, but allows customization of Promise library
|
|---|
| 49 | require('any-promise/register')('bluebird', {Promise: require('bluebird')})
|
|---|
| 50 | ```
|
|---|
| 51 |
|
|---|
| 52 | Now that the implementation is registered, you can use any package depending on `any-promise`:
|
|---|
| 53 |
|
|---|
| 54 |
|
|---|
| 55 | ```javascript
|
|---|
| 56 | var fsp = require('mz/fs') // mz/fs will use registered bluebird promises
|
|---|
| 57 | var Promise = require('any-promise') // the registered bluebird promise
|
|---|
| 58 | ```
|
|---|
| 59 |
|
|---|
| 60 | It is safe to call `register` multiple times, but it must always be with the same implementation.
|
|---|
| 61 |
|
|---|
| 62 | Again, registration is *optional*. It should only be called by the application user if overriding the global `Promise` implementation is desired.
|
|---|
| 63 |
|
|---|
| 64 | ### Optional Application Registration
|
|---|
| 65 |
|
|---|
| 66 | As an application author, you can *optionally* register a preferred `Promise` implementation on application startup (before any call to `require('any-promise')`:
|
|---|
| 67 |
|
|---|
| 68 | You must register your preference before any call to `require('any-promise')` (by you or required packages), and only one implementation can be registered. Typically, this registration would occur at the top of the application entry point.
|
|---|
| 69 |
|
|---|
| 70 |
|
|---|
| 71 | #### Registration shortcuts
|
|---|
| 72 |
|
|---|
| 73 | If you are using a known `Promise` implementation, you can register your preference with a shortcut:
|
|---|
| 74 |
|
|---|
| 75 |
|
|---|
| 76 | ```js
|
|---|
| 77 | require('any-promise/register/bluebird')
|
|---|
| 78 | // -or-
|
|---|
| 79 | import 'any-promise/register/q';
|
|---|
| 80 | ```
|
|---|
| 81 |
|
|---|
| 82 | Shortcut registration is the preferred registration method as it works in the browser and Node.js. It is also convenient for using with `import` and many test runners, that offer a `--require` flag:
|
|---|
| 83 |
|
|---|
| 84 | ```
|
|---|
| 85 | $ ava --require=any-promise/register/bluebird test.js
|
|---|
| 86 | ```
|
|---|
| 87 |
|
|---|
| 88 | Current known implementations include `bluebird`, `q`, `when`, `rsvp`, `es6-promise`, `promise`, `native-promise-only`, `pinkie`, `vow` and `lie`. If you are not using a known implementation, you can use another registration method described below.
|
|---|
| 89 |
|
|---|
| 90 |
|
|---|
| 91 | #### Basic Registration
|
|---|
| 92 |
|
|---|
| 93 | As an alternative to registration shortcuts, you can call the `register` function with the preferred `Promise` implementation. The benefit of this approach is that a `Promise` library can be required by name without being a known implementation. This approach does NOT work in the browser. To use `any-promise` in the browser use either registration shortcuts or specify the `Promise` constructor using advanced registration (see below).
|
|---|
| 94 |
|
|---|
| 95 | ```javascript
|
|---|
| 96 | require('any-promise/register')('when')
|
|---|
| 97 | // -or- require('any-promise/register')('any other ES6 compatible library (known or otherwise)')
|
|---|
| 98 | ```
|
|---|
| 99 |
|
|---|
| 100 | This registration method will try to detect the `Promise` constructor from requiring the specified implementation. If you would like to specify your own constructor, see advanced registration.
|
|---|
| 101 |
|
|---|
| 102 |
|
|---|
| 103 | #### Advanced Registration
|
|---|
| 104 |
|
|---|
| 105 | To use the browser version, you should either install a polyfill or explicitly register the `Promise` constructor:
|
|---|
| 106 |
|
|---|
| 107 | ```javascript
|
|---|
| 108 | require('any-promise/register')('bluebird', {Promise: require('bluebird')})
|
|---|
| 109 | ```
|
|---|
| 110 |
|
|---|
| 111 | This could also be used for registering a custom `Promise` implementation or subclass.
|
|---|
| 112 |
|
|---|
| 113 | Your preference will be registered globally, allowing a single registration even if multiple versions of `any-promise` are installed in the NPM dependency tree or are using multiple bundled JavaScript files in the browser. You can bypass this global registration in options:
|
|---|
| 114 |
|
|---|
| 115 |
|
|---|
| 116 | ```javascript
|
|---|
| 117 | require('../register')('es6-promise', {Promise: require('es6-promise').Promise, global: false})
|
|---|
| 118 | ```
|
|---|
| 119 |
|
|---|
| 120 | ### Library Usage
|
|---|
| 121 |
|
|---|
| 122 | To use any `Promise` constructor, simply require it:
|
|---|
| 123 |
|
|---|
| 124 | ```javascript
|
|---|
| 125 | var Promise = require('any-promise');
|
|---|
| 126 |
|
|---|
| 127 | return Promise
|
|---|
| 128 | .all([xf, f, init, coll])
|
|---|
| 129 | .then(fn);
|
|---|
| 130 |
|
|---|
| 131 |
|
|---|
| 132 | return new Promise(function(resolve, reject){
|
|---|
| 133 | try {
|
|---|
| 134 | resolve(item);
|
|---|
| 135 | } catch(e){
|
|---|
| 136 | reject(e);
|
|---|
| 137 | }
|
|---|
| 138 | });
|
|---|
| 139 |
|
|---|
| 140 | ```
|
|---|
| 141 |
|
|---|
| 142 | Except noted below, libraries using `any-promise` should only use [documented](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) functions as there is no guarantee which implementation will be chosen by the application author. Libraries should never call `register`, only the application user should call if desired.
|
|---|
| 143 |
|
|---|
| 144 |
|
|---|
| 145 | #### Advanced Library Usage
|
|---|
| 146 |
|
|---|
| 147 | If your library needs to branch code based on the registered implementation, you can retrieve it using `var impl = require('any-promise/implementation')`, where `impl` will be the package name (`"bluebird"`, `"when"`, etc.) if registered, `"global.Promise"` if using the global version on Node.js, or `"window.Promise"` if using the browser version. You should always include a default case, as there is no guarantee what package may be registered.
|
|---|
| 148 |
|
|---|
| 149 |
|
|---|
| 150 | ### Support for old Node.js versions
|
|---|
| 151 |
|
|---|
| 152 | Node.js versions prior to `v0.12` may have contained buggy versions of the global `Promise`. For this reason, the global `Promise` is not loaded automatically for these old versions. If using `any-promise` in Node.js versions versions `<= v0.12`, the user should register a desired implementation.
|
|---|
| 153 |
|
|---|
| 154 | If an implementation is not registered, `any-promise` will attempt to discover an installed `Promise` implementation. If no implementation can be found, an error will be thrown on `require('any-promise')`. While the auto-discovery usually avoids errors, it is non-deterministic. It is recommended that the user always register a preferred implementation for older Node.js versions.
|
|---|
| 155 |
|
|---|
| 156 | This auto-discovery is only available for Node.jS versions prior to `v0.12`. Any newer versions will always default to the global `Promise` implementation.
|
|---|
| 157 |
|
|---|
| 158 | ### Related
|
|---|
| 159 |
|
|---|
| 160 | - [any-observable](https://github.com/sindresorhus/any-observable) - `any-promise` for Observables.
|
|---|
| 161 |
|
|---|