Codebase list node-promise / 3345930
New upstream version 8.0.1 Pirate Praveen 6 years ago
27 changed file(s) with 1775 addition(s) and 366 deletion(s). Raw diff Collapse all Expand all
0 components
1 build
2 node_modules
3 /lib
4 /domains
5 /setimmediate
6 coverage
7 package-lock.json
33 .gitignore
44 .travis.yml
55 component.json
6 coverage
00 language: node_js
1 sudo: false
2
13 node_js:
2 - "0.7"
3 - "0.8"
4 - "0.9"
54 - "0.10"
5 - "0.12"
6 - "iojs"
7
8 after_success:
9 - npm run coverage
10 - npm i coveralls
11 - cat ./coverage/lcov.info | coveralls
0 <a href="http://promises-aplus.github.com/promises-spec"><img src="http://promises-aplus.github.com/promises-spec/assets/logo-small.png" align="right" /></a>
0 <a href="https://promisesaplus.com/"><img src="https://promisesaplus.com/assets/logo-small.png" align="right" /></a>
11 # promise
22
33 This is a simple implementation of Promises. It is a super set of ES6 Promises designed to have readable, performant code and to provide just the extensions that are absolutely necessary for using promises today.
44
55 For detailed tutorials on its use, see www.promisejs.org
66
7 [![Build Status](https://travis-ci.org/then/promise.png)](https://travis-ci.org/then/promise)
8 [![Dependency Status](https://gemnasium.com/then/promise.png)](https://gemnasium.com/then/promise)
9 [![NPM version](https://badge.fury.io/js/promise.png)](http://badge.fury.io/js/promise)
7 **N.B.** This promise exposes internals via underscore (`_`) prefixed properties. If you use these, your code will break with each new release.
8
9 [![travis][travis-image]][travis-url]
10 [![dep][dep-image]][dep-url]
11 [![npm][npm-image]][npm-url]
12 [![downloads][downloads-image]][downloads-url]
13
14 [travis-image]: https://img.shields.io/travis/then/promise.svg?style=flat
15 [travis-url]: https://travis-ci.org/then/promise
16 [dep-image]: https://img.shields.io/david/then/promise.svg?style=flat
17 [dep-url]: https://david-dm.org/then/promise
18 [npm-image]: https://img.shields.io/npm/v/promise.svg?style=flat
19 [npm-url]: https://npmjs.org/package/promise
20 [downloads-image]: https://img.shields.io/npm/dm/promise.svg?style=flat
21 [downloads-url]: https://npmjs.org/package/promise
1022
1123 ## Installation
1224
1628
1729 **Client:**
1830
19 You can use browserify on the client, or use the pre-compiled script that acts as a pollyfill.
31 You can use browserify on the client, or use the pre-compiled script that acts as a polyfill.
2032
2133 ```html
22 <script src="https://www.promisejs.org/polyfills/promise-4.0.0.js"></script>
34 <script src="https://www.promisejs.org/polyfills/promise-6.1.0.js"></script>
35 ```
36
37 Note that the [es5-shim](https://github.com/es-shims/es5-shim) must be loaded before this library to support browsers pre IE9.
38
39 ```html
40 <script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/3.4.0/es5-shim.min.js"></script>
2341 ```
2442
2543 ## Usage
2644
27 The example below shows how you can load the promise library (in a way that works on both client and server). It then demonstrates creating a promise from scratch. You simply call `new Promise(fn)`. There is a complete specification for what is returned by this method in [Promises/A+](http://promises-aplus.github.com/promises-spec/).
45 The example below shows how you can load the promise library (in a way that works on both client and server using node or browserify). It then demonstrates creating a promise from scratch. You simply call `new Promise(fn)`. There is a complete specification for what is returned by this method in [Promises/A+](http://promises-aplus.github.com/promises-spec/).
2846
2947 ```javascript
3048 var Promise = require('promise');
3755 });
3856 ```
3957
58 If you need [domains](https://iojs.org/api/domain.html) support, you should instead use:
59
60 ```js
61 var Promise = require('promise/domains');
62 ```
63
64 If you are in an environment that implements `setImmediate` and don't want the optimisations provided by asap, you can use:
65
66 ```js
67 var Promise = require('promise/setimmediate');
68 ```
69
70 If you only want part of the features, e.g. just a pure ES6 polyfill:
71
72 ```js
73 var Promise = require('promise/lib/es6-extensions');
74 // or require('promise/domains/es6-extensions');
75 // or require('promise/setimmediate/es6-extensions');
76 ```
77
78 ## Unhandled Rejections
79
80 By default, promises silence any unhandled rejections.
81
82 You can enable logging of unhandled ReferenceErrors and TypeErrors via:
83
84 ```js
85 require('promise/lib/rejection-tracking').enable();
86 ```
87
88 Due to the performance cost, you should only do this during development.
89
90 You can enable logging of all unhandled rejections if you need to debug an exception you think is being swallowed by promises:
91
92 ```js
93 require('promise/lib/rejection-tracking').enable(
94 {allRejections: true}
95 );
96 ```
97
98 Due to the high probability of false positives, I only recommend using this when debugging specific issues that you think may be being swallowed. For the preferred debugging method, see `Promise#done(onFulfilled, onRejected)`.
99
100 `rejection-tracking.enable(options)` takes the following options:
101
102 - allRejections (`boolean`) - track all exceptions, not just reference errors and type errors. Note that this has a high probability of resulting in false positives if your code loads data optimisticly
103 - whitelist (`Array<ErrorConstructor>`) - this defaults to `[ReferenceError, TypeError]` but you can override it with your own list of error constructors to track.
104 - `onUnhandled(id, error)` and `onHandled(id, error)` - you can use these to provide your own customised display for errors. Note that if possible you should indicate that the error was a false positive if `onHandled` is called. `onHandled` is only called if `onUnhandled` has already been called.
105
106 To reduce the chance of false-positives there is a delay of up to 2 seconds before errors are logged. This means that if you attach an error handler within 2 seconds, it won't be logged as a false positive. ReferenceErrors and TypeErrors are only subject to a 100ms delay due to the higher likelihood that the error is due to programmer error.
107
40108 ## API
41109
42110 Before all examples, you will need:
62130
63131 Converts values and foreign promises into Promises/A+ promises. If you pass it a value then it returns a Promise for that value. If you pass it something that is close to a promise (such as a jQuery attempt at a promise) it returns a Promise that takes on the state of `value` (rejected or fulfilled).
64132
133 #### Promise.reject(value)
134
135 Returns a rejected promise with the given value.
136
65137 #### Promise.all(array)
66138
67 Returns a promise for an array. If it is called with a single argument that `Array.isArray` then this returns a promise for a copy of that array with any promises replaced by their fulfilled values. Otherwise it returns a promise for an array that conatins its arguments, except with promises replaced by their resolution values. e.g.
68
69 ```js
70 Promise.all([Promise.from('a'), 'b', Promise.from('c')])
139 Returns a promise for an array. If it is called with a single argument that `Array.isArray` then this returns a promise for a copy of that array with any promises replaced by their fulfilled values. e.g.
140
141 ```js
142 Promise.all([Promise.resolve('a'), 'b', Promise.resolve('c')])
71143 .then(function (res) {
72144 assert(res[0] === 'a')
73145 assert(res[1] === 'b')
74146 assert(res[2] === 'c')
75147 })
76
77 Promise.all(Promise.from('a'), 'b', Promise.from('c'))
78 .then(function (res) {
79 assert(res[0] === 'a')
80 assert(res[1] === 'b')
81 assert(res[2] === 'c')
82 })
83148 ```
84149
85150 #### Promise.denodeify(fn)
130195 If the promise is fulfilled then `onFulfilled` is called. If the promise is rejected then `onRejected` is called.
131196
132197 The call to `.then` also returns a promise. If the handler that is called returns a promise, the promise returned by `.then` takes on the state of that returned promise. If the handler that is called returns a value that is not a promise, the promise returned by `.then` will be fulfilled with that value. If the handler that is called throws an exception then the promise returned by `.then` is rejected with that exception.
198
199 #### Promise#catch(onRejected)
200
201 Sugar for `Promise#then(null, onRejected)`, to mirror `catch` in synchronous code.
133202
134203 #### Promise#done(onFulfilled, onRejected)
135204
156225
157226 People who use typical node.js style callbacks will be able to just pass a callback and get the expected behavior. The enlightened people can not pass a callback and will get awesome promises.
158227
159 ## Extending Promises
160
161 There are three options for extending the promises created by this library.
162
163 ### Inheritance
164
165 You can use inheritance if you want to create your own complete promise library with this as your basic starting point, perfect if you have lots of cool features you want to add. Here is an example of a promise library called `Awesome`, which is built on top of `Promise` correctly.
166
167 ```javascript
168 var Promise = require('promise');
169 function Awesome(fn) {
170 if (!(this instanceof Awesome)) return new Awesome(fn);
171 Promise.call(this, fn);
172 }
173 Awesome.prototype = Object.create(Promise.prototype);
174 Awesome.prototype.constructor = Awesome;
175
176 //Awesome extension
177 Awesome.prototype.spread = function (cb) {
178 return this.then(function (arr) {
179 return cb.apply(this, arr);
180 })
181 };
182 ```
183
184 N.B. if you fail to set the prototype and constructor properly or fail to do Promise.call, things can fail in really subtle ways.
185
186 ### Wrap
187
188 This is the nuclear option, for when you want to start from scratch. It ensures you won't be impacted by anyone who is extending the prototype (see below).
189
190 ```javascript
191 function Uber(fn) {
192 if (!(this instanceof Uber)) return new Uber(fn);
193 var _prom = new Promise(fn);
194 this.then = _prom.then;
195 }
196
197 Uber.prototype.spread = function (cb) {
198 return this.then(function (arr) {
199 return cb.apply(this, arr);
200 })
201 };
202 ```
203
204 ### Extending the Prototype
205
206 In general, you should never extend the prototype of this promise implimenation because your extensions could easily conflict with someone elses extensions. However, this organisation will host a library of extensions which do not conflict with each other, so you can safely enable any of those. If you think of an extension that we don't provide and you want to write it, submit an issue on this repository and (if I agree) I'll set you up with a repository and give you permission to commit to it.
207
208228 ## License
209229
210230 MIT
0 'use strict';
1
2 var fs = require('fs');
3 var rimraf = require('rimraf');
4 var acorn = require('acorn');
5 var walk = require('acorn/dist/walk');
6
7 var ids = [];
8 var names = {};
9
10 function getIdFor(name) {
11 if (name in names) return names[name];
12 var id;
13 do {
14 id = '_' + Math.floor(Math.random() * 100);
15 } while (ids.indexOf(id) !== -1)
16 ids.push(id);
17 names[name] = id;
18 return id;
19 }
20
21 function fixup(src) {
22 var ast = acorn.parse(src);
23 src = src.split('');
24 walk.simple(ast, {
25 MemberExpression: function (node) {
26 if (node.computed) return;
27 if (node.property.type !== 'Identifier') return;
28 if (node.property.name[0] !== '_') return;
29 replace(node.property, getIdFor(node.property.name));
30 }
31 });
32 function source(node) {
33 return src.slice(node.start, node.end).join('');
34 }
35 function replace(node, str) {
36 for (var i = node.start; i < node.end; i++) {
37 src[i] = '';
38 }
39 src[node.start] = str;
40 }
41 return src.join('');
42 }
43 rimraf.sync(__dirname + '/lib/');
44 fs.mkdirSync(__dirname + '/lib/');
45 fs.readdirSync(__dirname + '/src').forEach(function (filename) {
46 var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8');
47 var out = fixup(src);
48 fs.writeFileSync(__dirname + '/lib/' + filename, out);
49 });
50
51 rimraf.sync(__dirname + '/domains/');
52 fs.mkdirSync(__dirname + '/domains/');
53 fs.readdirSync(__dirname + '/src').forEach(function (filename) {
54 var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8');
55 var out = fixup(src);
56 out = out.replace(/require\(\'asap\/raw\'\)/g, "require('asap')");
57 fs.writeFileSync(__dirname + '/domains/' + filename, out);
58 });
59
60 rimraf.sync(__dirname + '/setimmediate/');
61 fs.mkdirSync(__dirname + '/setimmediate/');
62 fs.readdirSync(__dirname + '/src').forEach(function (filename) {
63 var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8');
64 var out = fixup(src);
65 out = out.replace(/var asap \= require\(\'([a-z\/]+)\'\);/g, '');
66 out = out.replace(/asap/g, "setImmediate");
67 fs.writeFileSync(__dirname + '/setimmediate/' + filename, out);
68 });
11 "name": "promise",
22 "repo": "then/promise",
33 "description": "Bare bones Promises/A+ implementation",
4 "version": "5.0.0",
4 "version": "8.0.1",
55 "keywords": [],
66 "dependencies": {
77 "johntron/asap": "*"
88 },
99 "development": {},
1010 "license": "MIT",
11 "main": "index.js",
1112 "scripts": [
1213 "index.js",
13 "core.js"
14 "lib/core.js",
15 "lib/done.js",
16 "lib/es6-extensions.js",
17 "lib/node-extensions.js"
1418 ],
1519 "twitter": "@ForbesLindesay"
1620 }
00 'use strict';
11
2 var asap = require('asap')
2 module.exports = require('./lib/core.js');
33
4 module.exports = Promise
5 function Promise(fn) {
6 if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new')
7 if (typeof fn !== 'function') throw new TypeError('not a function')
8 var state = null
9 var value = null
10 var deferreds = []
11 var self = this
12
13 this.then = function(onFulfilled, onRejected) {
14 return new Promise(function(resolve, reject) {
15 handle(new Handler(onFulfilled, onRejected, resolve, reject))
16 })
17 }
18
19 function handle(deferred) {
20 if (state === null) {
21 deferreds.push(deferred)
22 return
23 }
24 asap(function() {
25 var cb = state ? deferred.onFulfilled : deferred.onRejected
26 if (cb === null) {
27 (state ? deferred.resolve : deferred.reject)(value)
28 return
29 }
30 var ret
31 try {
32 ret = cb(value)
33 }
34 catch (e) {
35 deferred.reject(e)
36 return
37 }
38 deferred.resolve(ret)
39 })
40 }
41
42 function resolve(newValue) {
43 try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
44 if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.')
45 if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
46 var then = newValue.then
47 if (typeof then === 'function') {
48 doResolve(then.bind(newValue), resolve, reject)
49 return
50 }
51 }
52 state = true
53 value = newValue
54 finale()
55 } catch (e) { reject(e) }
56 }
57
58 function reject(newValue) {
59 state = false
60 value = newValue
61 finale()
62 }
63
64 function finale() {
65 for (var i = 0, len = deferreds.length; i < len; i++)
66 handle(deferreds[i])
67 deferreds = null
68 }
69
70 doResolve(fn, resolve, reject)
71 }
72
73
74 function Handler(onFulfilled, onRejected, resolve, reject){
75 this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null
76 this.onRejected = typeof onRejected === 'function' ? onRejected : null
77 this.resolve = resolve
78 this.reject = reject
79 }
80
81 /**
82 * Take a potentially misbehaving resolver function and make sure
83 * onFulfilled and onRejected are only called once.
84 *
85 * Makes no guarantees about asynchrony.
86 */
87 function doResolve(fn, onFulfilled, onRejected) {
88 var done = false;
89 try {
90 fn(function (value) {
91 if (done) return
92 done = true
93 onFulfilled(value)
94 }, function (reason) {
95 if (done) return
96 done = true
97 onRejected(reason)
98 })
99 } catch (ex) {
100 if (done) return
101 done = true
102 onRejected(ex)
103 }
104 }
4 console.error('require("promise/core") is deprecated, use require("promise/lib/core") instead.');
0 /**
1 * Represents the completion of an asynchronous operation
2 */
3 interface ThenPromise<T> extends Promise<T> {
4 /**
5 * Attaches callbacks for the resolution and/or rejection of the ThenPromise.
6 * @param onfulfilled The callback to execute when the ThenPromise is resolved.
7 * @param onrejected The callback to execute when the ThenPromise is rejected.
8 * @returns A ThenPromise for the completion of which ever callback is executed.
9 */
10 then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): ThenPromise<TResult1 | TResult2>;
11
12 /**
13 * Attaches a callback for only the rejection of the ThenPromise.
14 * @param onrejected The callback to execute when the ThenPromise is rejected.
15 * @returns A ThenPromise for the completion of the callback.
16 */
17 catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): ThenPromise<T | TResult>;
18
19 // Extensions specific to then/promise
20
21 /**
22 * Attaches callbacks for the resolution and/or rejection of the ThenPromise, without returning a new promise.
23 * @param onfulfilled The callback to execute when the ThenPromise is resolved.
24 * @param onrejected The callback to execute when the ThenPromise is rejected.
25 */
26 done(onfulfilled?: ((value: T) => any) | undefined | null, onrejected?: ((reason: any) => any) | undefined | null): void;
27
28
29 /**
30 * Calls a node.js style callback. If none is provided, the promise is returned.
31 */
32 nodeify(callback: void | null): ThenPromise<T>;
33 nodeify(callback: (err: Error, value: T) => void): void;
34 }
35
36 interface ThenPromiseConstructor {
37 /**
38 * A reference to the prototype.
39 */
40 readonly prototype: ThenPromise<any>;
41
42 /**
43 * Creates a new ThenPromise.
44 * @param executor A callback used to initialize the promise. This callback is passed two arguments:
45 * a resolve callback used resolve the promise with a value or the result of another promise,
46 * and a reject callback used to reject the promise with a provided reason or error.
47 */
48 new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => any): ThenPromise<T>;
49
50 /**
51 * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
52 * resolve, or rejected when any ThenPromise is rejected.
53 * @param values An array of Promises.
54 * @returns A new ThenPromise.
55 */
56 all<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>, T10 | PromiseLike<T10>]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>;
57
58 /**
59 * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
60 * resolve, or rejected when any ThenPromise is rejected.
61 * @param values An array of Promises.
62 * @returns A new ThenPromise.
63 */
64 all<T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>;
65
66 /**
67 * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
68 * resolve, or rejected when any ThenPromise is rejected.
69 * @param values An array of Promises.
70 * @returns A new ThenPromise.
71 */
72 all<T1, T2, T3, T4, T5, T6, T7, T8>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8]>;
73
74 /**
75 * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
76 * resolve, or rejected when any ThenPromise is rejected.
77 * @param values An array of Promises.
78 * @returns A new ThenPromise.
79 */
80 all<T1, T2, T3, T4, T5, T6, T7>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7]>;
81
82 /**
83 * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
84 * resolve, or rejected when any ThenPromise is rejected.
85 * @param values An array of Promises.
86 * @returns A new ThenPromise.
87 */
88 all<T1, T2, T3, T4, T5, T6>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>]): ThenPromise<[T1, T2, T3, T4, T5, T6]>;
89
90 /**
91 * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
92 * resolve, or rejected when any ThenPromise is rejected.
93 * @param values An array of Promises.
94 * @returns A new ThenPromise.
95 */
96 all<T1, T2, T3, T4, T5>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>]): ThenPromise<[T1, T2, T3, T4, T5]>;
97
98 /**
99 * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
100 * resolve, or rejected when any ThenPromise is rejected.
101 * @param values An array of Promises.
102 * @returns A new ThenPromise.
103 */
104 all<T1, T2, T3, T4>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>]): ThenPromise<[T1, T2, T3, T4]>;
105
106 /**
107 * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
108 * resolve, or rejected when any ThenPromise is rejected.
109 * @param values An array of Promises.
110 * @returns A new ThenPromise.
111 */
112 all<T1, T2, T3>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): ThenPromise<[T1, T2, T3]>;
113
114 /**
115 * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
116 * resolve, or rejected when any ThenPromise is rejected.
117 * @param values An array of Promises.
118 * @returns A new ThenPromise.
119 */
120 all<T1, T2>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): ThenPromise<[T1, T2]>;
121
122 /**
123 * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
124 * resolve, or rejected when any ThenPromise is rejected.
125 * @param values An array of Promises.
126 * @returns A new ThenPromise.
127 */
128 all<T>(values: (T | PromiseLike<T>)[]): ThenPromise<T[]>;
129
130 /**
131 * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
132 * or rejected.
133 * @param values An array of Promises.
134 * @returns A new ThenPromise.
135 */
136 race<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>, T10 | PromiseLike<T10>]): ThenPromise<T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8 | T9 | T10>;
137
138 /**
139 * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
140 * or rejected.
141 * @param values An array of Promises.
142 * @returns A new ThenPromise.
143 */
144 race<T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>]): ThenPromise<T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8 | T9>;
145
146 /**
147 * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
148 * or rejected.
149 * @param values An array of Promises.
150 * @returns A new ThenPromise.
151 */
152 race<T1, T2, T3, T4, T5, T6, T7, T8>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>]): ThenPromise<T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8>;
153
154 /**
155 * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
156 * or rejected.
157 * @param values An array of Promises.
158 * @returns A new ThenPromise.
159 */
160 race<T1, T2, T3, T4, T5, T6, T7>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>]): ThenPromise<T1 | T2 | T3 | T4 | T5 | T6 | T7>;
161
162 /**
163 * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
164 * or rejected.
165 * @param values An array of Promises.
166 * @returns A new ThenPromise.
167 */
168 race<T1, T2, T3, T4, T5, T6>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>]): ThenPromise<T1 | T2 | T3 | T4 | T5 | T6>;
169
170 /**
171 * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
172 * or rejected.
173 * @param values An array of Promises.
174 * @returns A new ThenPromise.
175 */
176 race<T1, T2, T3, T4, T5>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>]): ThenPromise<T1 | T2 | T3 | T4 | T5>;
177
178 /**
179 * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
180 * or rejected.
181 * @param values An array of Promises.
182 * @returns A new ThenPromise.
183 */
184 race<T1, T2, T3, T4>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>]): ThenPromise<T1 | T2 | T3 | T4>;
185
186 /**
187 * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
188 * or rejected.
189 * @param values An array of Promises.
190 * @returns A new ThenPromise.
191 */
192 race<T1, T2, T3>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): ThenPromise<T1 | T2 | T3>;
193
194 /**
195 * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
196 * or rejected.
197 * @param values An array of Promises.
198 * @returns A new ThenPromise.
199 */
200 race<T1, T2>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): ThenPromise<T1 | T2>;
201
202 /**
203 * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
204 * or rejected.
205 * @param values An array of Promises.
206 * @returns A new ThenPromise.
207 */
208 race<T>(values: (T | PromiseLike<T>)[]): ThenPromise<T>;
209
210 /**
211 * Creates a new rejected promise for the provided reason.
212 * @param reason The reason the promise was rejected.
213 * @returns A new rejected ThenPromise.
214 */
215 reject(reason: any): ThenPromise<never>;
216
217 /**
218 * Creates a new rejected promise for the provided reason.
219 * @param reason The reason the promise was rejected.
220 * @returns A new rejected ThenPromise.
221 */
222 reject<T>(reason: any): ThenPromise<T>;
223
224 /**
225 * Creates a new resolved promise for the provided value.
226 * @param value A promise.
227 * @returns A promise whose internal state matches the provided promise.
228 */
229 resolve<T>(value: T | PromiseLike<T>): ThenPromise<T>;
230
231 /**
232 * Creates a new resolved promise .
233 * @returns A resolved promise.
234 */
235 resolve(): ThenPromise<void>;
236
237 // Extensions specific to then/promise
238
239 denodeify: (fn: Function) => (...args: any[]) => ThenPromise<any>;
240 nodeify: (fn: Function) => Function;
241 }
242
243 declare var ThenPromise: ThenPromiseConstructor;
244
245 export = ThenPromise;
00 'use strict';
11
2 //This file contains then/promise specific extensions to the core promise API
3
4 var Promise = require('./core.js')
5 var asap = require('asap')
6
7 module.exports = Promise
8
9 /* Static Functions */
10
11 function ValuePromise(value) {
12 this.then = function (onFulfilled) {
13 if (typeof onFulfilled !== 'function') return this
14 return new Promise(function (resolve, reject) {
15 asap(function () {
16 try {
17 resolve(onFulfilled(value))
18 } catch (ex) {
19 reject(ex);
20 }
21 })
22 })
23 }
24 }
25 ValuePromise.prototype = Object.create(Promise.prototype)
26
27 var TRUE = new ValuePromise(true)
28 var FALSE = new ValuePromise(false)
29 var NULL = new ValuePromise(null)
30 var UNDEFINED = new ValuePromise(undefined)
31 var ZERO = new ValuePromise(0)
32 var EMPTYSTRING = new ValuePromise('')
33
34 Promise.resolve = function (value) {
35 if (value instanceof Promise) return value
36
37 if (value === null) return NULL
38 if (value === undefined) return UNDEFINED
39 if (value === true) return TRUE
40 if (value === false) return FALSE
41 if (value === 0) return ZERO
42 if (value === '') return EMPTYSTRING
43
44 if (typeof value === 'object' || typeof value === 'function') {
45 try {
46 var then = value.then
47 if (typeof then === 'function') {
48 return new Promise(then.bind(value))
49 }
50 } catch (ex) {
51 return new Promise(function (resolve, reject) {
52 reject(ex)
53 })
54 }
55 }
56
57 return new ValuePromise(value)
58 }
59
60 Promise.from = Promise.cast = function (value) {
61 var err = new Error('Promise.from and Promise.cast are deprecated, use Promise.resolve instead')
62 err.name = 'Warning'
63 console.warn(err.stack)
64 return Promise.resolve(value)
65 }
66
67 Promise.denodeify = function (fn, argumentCount) {
68 argumentCount = argumentCount || Infinity
69 return function () {
70 var self = this
71 var args = Array.prototype.slice.call(arguments)
72 return new Promise(function (resolve, reject) {
73 while (args.length && args.length > argumentCount) {
74 args.pop()
75 }
76 args.push(function (err, res) {
77 if (err) reject(err)
78 else resolve(res)
79 })
80 fn.apply(self, args)
81 })
82 }
83 }
84 Promise.nodeify = function (fn) {
85 return function () {
86 var args = Array.prototype.slice.call(arguments)
87 var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null
88 try {
89 return fn.apply(this, arguments).nodeify(callback)
90 } catch (ex) {
91 if (callback === null || typeof callback == 'undefined') {
92 return new Promise(function (resolve, reject) { reject(ex) })
93 } else {
94 asap(function () {
95 callback(ex)
96 })
97 }
98 }
99 }
100 }
101
102 Promise.all = function () {
103 var calledWithArray = arguments.length === 1 && Array.isArray(arguments[0])
104 var args = Array.prototype.slice.call(calledWithArray ? arguments[0] : arguments)
105
106 if (!calledWithArray) {
107 var err = new Error('Promise.all should be called with a single array, calling it with multiple arguments is deprecated')
108 err.name = 'Warning'
109 console.warn(err.stack)
110 }
111
112 return new Promise(function (resolve, reject) {
113 if (args.length === 0) return resolve([])
114 var remaining = args.length
115 function res(i, val) {
116 try {
117 if (val && (typeof val === 'object' || typeof val === 'function')) {
118 var then = val.then
119 if (typeof then === 'function') {
120 then.call(val, function (val) { res(i, val) }, reject)
121 return
122 }
123 }
124 args[i] = val
125 if (--remaining === 0) {
126 resolve(args);
127 }
128 } catch (ex) {
129 reject(ex)
130 }
131 }
132 for (var i = 0; i < args.length; i++) {
133 res(i, args[i])
134 }
135 })
136 }
137
138 Promise.reject = function (value) {
139 return new Promise(function (resolve, reject) {
140 reject(value);
141 });
142 }
143
144 Promise.race = function (values) {
145 return new Promise(function (resolve, reject) {
146 values.forEach(function(value){
147 Promise.resolve(value).then(resolve, reject);
148 })
149 });
150 }
151
152 /* Prototype Methods */
153
154 Promise.prototype.done = function (onFulfilled, onRejected) {
155 var self = arguments.length ? this.then.apply(this, arguments) : this
156 self.then(null, function (err) {
157 asap(function () {
158 throw err
159 })
160 })
161 }
162
163 Promise.prototype.nodeify = function (callback) {
164 if (typeof callback != 'function') return this
165
166 this.then(function (value) {
167 asap(function () {
168 callback(null, value)
169 })
170 }, function (err) {
171 asap(function () {
172 callback(err)
173 })
174 })
175 }
176
177 Promise.prototype['catch'] = function (onRejected) {
178 return this.then(null, onRejected);
179 }
2 module.exports = require('./lib')
0 // @flow
1
2 declare class ThenPromise<+R> extends Promise<R> {
3 constructor(callback: (
4 resolve: (result: Promise<R> | R) => void,
5 reject: (error: any) => void
6 ) => mixed): void;
7
8 then<U>(
9 onFulfill?: (value: R) => Promise<U> | U,
10 onReject?: (error: any) => Promise<U> | U
11 ): ThenPromise<U>;
12
13 catch<U>(
14 onReject?: (error: any) => Promise<U> | U
15 ): ThenPromise<R | U>;
16
17 // Extensions specific to then/promise
18
19 /**
20 * Attaches callbacks for the resolution and/or rejection of the ThenPromise, without returning a new promise.
21 * @param onfulfilled The callback to execute when the ThenPromise is resolved.
22 * @param onrejected The callback to execute when the ThenPromise is rejected.
23 */
24 done(onfulfilled?: (value: R) => any, onrejected?: (reason: any) => any): void;
25
26
27 /**
28 * Calls a node.js style callback. If none is provided, the promise is returned.
29 */
30 nodeify(callback: void | null): ThenPromise<R>;
31 nodeify(callback: (err: Error, value: R) => void): void;
32
33 static resolve<T>(object: Promise<T> | T): ThenPromise<T>;
34 static reject<T>(error?: any): ThenPromise<T>;
35 static all<Elem, T:Iterable<Elem>>(promises: T): ThenPromise<$TupleMap<T, typeof $await>>;
36 static race<T, Elem: Promise<T> | T>(promises: Array<Elem>): ThenPromise<T>;
37
38 // Extensions specific to then/promise
39
40 static denodeify(fn: Function): (...args: any[]) => ThenPromise<any>;
41 static nodeify(fn: Function): Function;
42 }
43 module.exports = ThenPromise;
00 {
11 "name": "promise",
2 "version": "5.0.0",
2 "version": "8.0.1",
33 "description": "Bare bones Promises/A+ implementation",
44 "main": "index.js",
55 "scripts": {
6 "test": "mocha -R spec --timeout 200 --slow 99999",
7 "test-resolve": "mocha test/resolver-tests.js -R spec --timeout 200 --slow 999999",
8 "test-extensions": "mocha test/extensions-tests.js -R spec --timeout 200 --slow 999999"
6 "prepublish": "node build",
7 "pretest": "node build",
8 "pretest-resolve": "node build",
9 "pretest-extensions": "node build",
10 "pretest-memory-leak": "node build",
11 "test": "mocha --bail --timeout 200 --slow 99999 -R dot && npm run test-memory-leak",
12 "test-resolve": "mocha test/resolver-tests.js --timeout 200 --slow 999999",
13 "test-extensions": "mocha test/extensions-tests.js --timeout 200 --slow 999999",
14 "test-memory-leak": "node --expose-gc test/memory-leak.js",
15 "coverage": "istanbul cover node_modules/mocha/bin/_mocha -- --bail --timeout 200 --slow 99999 -R dot"
916 },
1017 "repository": {
1118 "type": "git",
1421 "author": "ForbesLindesay",
1522 "license": "MIT",
1623 "devDependencies": {
24 "acorn": "^1.0.1",
25 "better-assert": "*",
26 "istanbul": "^0.3.13",
27 "mocha": "*",
1728 "promises-aplus-tests": "*",
18 "better-assert": "*",
19 "mocha": "*"
29 "rimraf": "^2.3.2"
2030 },
2131 "dependencies": {
22 "asap": "~1.0.0"
32 "asap": "~2.0.3"
2333 }
2434 }
0 // should work in any browser without browserify
1
2 if (typeof Promise.prototype.done !== 'function') {
3 Promise.prototype.done = function (onFulfilled, onRejected) {
4 var self = arguments.length ? this.then.apply(this, arguments) : this
5 self.then(null, function (err) {
6 setTimeout(function () {
7 throw err
8 }, 0)
9 })
10 }
11 }
0 // not "use strict" so we can declare global "Promise"
1
2 var asap = require('asap');
3
4 if (typeof Promise === 'undefined') {
5 Promise = require('./lib/core.js')
6 require('./lib/es6-extensions.js')
7 }
8
9 require('./polyfill-done.js');
0 'use strict';
1
2 var asap = require('asap/raw');
3
4 function noop() {}
5
6 // States:
7 //
8 // 0 - pending
9 // 1 - fulfilled with _value
10 // 2 - rejected with _value
11 // 3 - adopted the state of another promise, _value
12 //
13 // once the state is no longer pending (0) it is immutable
14
15 // All `_` prefixed properties will be reduced to `_{random number}`
16 // at build time to obfuscate them and discourage their use.
17 // We don't use symbols or Object.defineProperty to fully hide them
18 // because the performance isn't good enough.
19
20
21 // to avoid using try/catch inside critical functions, we
22 // extract them to here.
23 var LAST_ERROR = null;
24 var IS_ERROR = {};
25 function getThen(obj) {
26 try {
27 return obj.then;
28 } catch (ex) {
29 LAST_ERROR = ex;
30 return IS_ERROR;
31 }
32 }
33
34 function tryCallOne(fn, a) {
35 try {
36 return fn(a);
37 } catch (ex) {
38 LAST_ERROR = ex;
39 return IS_ERROR;
40 }
41 }
42 function tryCallTwo(fn, a, b) {
43 try {
44 fn(a, b);
45 } catch (ex) {
46 LAST_ERROR = ex;
47 return IS_ERROR;
48 }
49 }
50
51 module.exports = Promise;
52
53 function Promise(fn) {
54 if (typeof this !== 'object') {
55 throw new TypeError('Promises must be constructed via new');
56 }
57 if (typeof fn !== 'function') {
58 throw new TypeError('Promise constructor\'s argument is not a function');
59 }
60 this._deferredState = 0;
61 this._state = 0;
62 this._value = null;
63 this._deferreds = null;
64 if (fn === noop) return;
65 doResolve(fn, this);
66 }
67 Promise._onHandle = null;
68 Promise._onReject = null;
69 Promise._noop = noop;
70
71 Promise.prototype.then = function(onFulfilled, onRejected) {
72 if (this.constructor !== Promise) {
73 return safeThen(this, onFulfilled, onRejected);
74 }
75 var res = new Promise(noop);
76 handle(this, new Handler(onFulfilled, onRejected, res));
77 return res;
78 };
79
80 function safeThen(self, onFulfilled, onRejected) {
81 return new self.constructor(function (resolve, reject) {
82 var res = new Promise(noop);
83 res.then(resolve, reject);
84 handle(self, new Handler(onFulfilled, onRejected, res));
85 });
86 }
87 function handle(self, deferred) {
88 while (self._state === 3) {
89 self = self._value;
90 }
91 if (Promise._onHandle) {
92 Promise._onHandle(self);
93 }
94 if (self._state === 0) {
95 if (self._deferredState === 0) {
96 self._deferredState = 1;
97 self._deferreds = deferred;
98 return;
99 }
100 if (self._deferredState === 1) {
101 self._deferredState = 2;
102 self._deferreds = [self._deferreds, deferred];
103 return;
104 }
105 self._deferreds.push(deferred);
106 return;
107 }
108 handleResolved(self, deferred);
109 }
110
111 function handleResolved(self, deferred) {
112 asap(function() {
113 var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
114 if (cb === null) {
115 if (self._state === 1) {
116 resolve(deferred.promise, self._value);
117 } else {
118 reject(deferred.promise, self._value);
119 }
120 return;
121 }
122 var ret = tryCallOne(cb, self._value);
123 if (ret === IS_ERROR) {
124 reject(deferred.promise, LAST_ERROR);
125 } else {
126 resolve(deferred.promise, ret);
127 }
128 });
129 }
130 function resolve(self, newValue) {
131 // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
132 if (newValue === self) {
133 return reject(
134 self,
135 new TypeError('A promise cannot be resolved with itself.')
136 );
137 }
138 if (
139 newValue &&
140 (typeof newValue === 'object' || typeof newValue === 'function')
141 ) {
142 var then = getThen(newValue);
143 if (then === IS_ERROR) {
144 return reject(self, LAST_ERROR);
145 }
146 if (
147 then === self.then &&
148 newValue instanceof Promise
149 ) {
150 self._state = 3;
151 self._value = newValue;
152 finale(self);
153 return;
154 } else if (typeof then === 'function') {
155 doResolve(then.bind(newValue), self);
156 return;
157 }
158 }
159 self._state = 1;
160 self._value = newValue;
161 finale(self);
162 }
163
164 function reject(self, newValue) {
165 self._state = 2;
166 self._value = newValue;
167 if (Promise._onReject) {
168 Promise._onReject(self, newValue);
169 }
170 finale(self);
171 }
172 function finale(self) {
173 if (self._deferredState === 1) {
174 handle(self, self._deferreds);
175 self._deferreds = null;
176 }
177 if (self._deferredState === 2) {
178 for (var i = 0; i < self._deferreds.length; i++) {
179 handle(self, self._deferreds[i]);
180 }
181 self._deferreds = null;
182 }
183 }
184
185 function Handler(onFulfilled, onRejected, promise){
186 this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
187 this.onRejected = typeof onRejected === 'function' ? onRejected : null;
188 this.promise = promise;
189 }
190
191 /**
192 * Take a potentially misbehaving resolver function and make sure
193 * onFulfilled and onRejected are only called once.
194 *
195 * Makes no guarantees about asynchrony.
196 */
197 function doResolve(fn, promise) {
198 var done = false;
199 var res = tryCallTwo(fn, function (value) {
200 if (done) return;
201 done = true;
202 resolve(promise, value);
203 }, function (reason) {
204 if (done) return;
205 done = true;
206 reject(promise, reason);
207 });
208 if (!done && res === IS_ERROR) {
209 done = true;
210 reject(promise, LAST_ERROR);
211 }
212 }
0 'use strict';
1
2 var Promise = require('./core.js');
3
4 module.exports = Promise;
5 Promise.prototype.done = function (onFulfilled, onRejected) {
6 var self = arguments.length ? this.then.apply(this, arguments) : this;
7 self.then(null, function (err) {
8 setTimeout(function () {
9 throw err;
10 }, 0);
11 });
12 };
0 'use strict';
1
2 //This file contains the ES6 extensions to the core Promises/A+ API
3
4 var Promise = require('./core.js');
5
6 module.exports = Promise;
7
8 /* Static Functions */
9
10 var TRUE = valuePromise(true);
11 var FALSE = valuePromise(false);
12 var NULL = valuePromise(null);
13 var UNDEFINED = valuePromise(undefined);
14 var ZERO = valuePromise(0);
15 var EMPTYSTRING = valuePromise('');
16
17 function valuePromise(value) {
18 var p = new Promise(Promise._noop);
19 p._state = 1;
20 p._value = value;
21 return p;
22 }
23 Promise.resolve = function (value) {
24 if (value instanceof Promise) return value;
25
26 if (value === null) return NULL;
27 if (value === undefined) return UNDEFINED;
28 if (value === true) return TRUE;
29 if (value === false) return FALSE;
30 if (value === 0) return ZERO;
31 if (value === '') return EMPTYSTRING;
32
33 if (typeof value === 'object' || typeof value === 'function') {
34 try {
35 var then = value.then;
36 if (typeof then === 'function') {
37 return new Promise(then.bind(value));
38 }
39 } catch (ex) {
40 return new Promise(function (resolve, reject) {
41 reject(ex);
42 });
43 }
44 }
45 return valuePromise(value);
46 };
47
48 Promise.all = function (arr) {
49 var args = Array.prototype.slice.call(arr);
50
51 return new Promise(function (resolve, reject) {
52 if (args.length === 0) return resolve([]);
53 var remaining = args.length;
54 function res(i, val) {
55 if (val && (typeof val === 'object' || typeof val === 'function')) {
56 if (val instanceof Promise && val.then === Promise.prototype.then) {
57 while (val._state === 3) {
58 val = val._value;
59 }
60 if (val._state === 1) return res(i, val._value);
61 if (val._state === 2) reject(val._value);
62 val.then(function (val) {
63 res(i, val);
64 }, reject);
65 return;
66 } else {
67 var then = val.then;
68 if (typeof then === 'function') {
69 var p = new Promise(then.bind(val));
70 p.then(function (val) {
71 res(i, val);
72 }, reject);
73 return;
74 }
75 }
76 }
77 args[i] = val;
78 if (--remaining === 0) {
79 resolve(args);
80 }
81 }
82 for (var i = 0; i < args.length; i++) {
83 res(i, args[i]);
84 }
85 });
86 };
87
88 Promise.reject = function (value) {
89 return new Promise(function (resolve, reject) {
90 reject(value);
91 });
92 };
93
94 Promise.race = function (values) {
95 return new Promise(function (resolve, reject) {
96 values.forEach(function(value){
97 Promise.resolve(value).then(resolve, reject);
98 });
99 });
100 };
101
102 /* Prototype Methods */
103
104 Promise.prototype['catch'] = function (onRejected) {
105 return this.then(null, onRejected);
106 };
0 'use strict';
1
2 var Promise = require('./core.js');
3
4 module.exports = Promise;
5 Promise.prototype['finally'] = function (f) {
6 return this.then(function (value) {
7 return Promise.resolve(f()).then(function () {
8 return value;
9 });
10 }, function (err) {
11 return Promise.resolve(f()).then(function () {
12 throw err;
13 });
14 });
15 };
0 'use strict';
1
2 module.exports = require('./core.js');
3 require('./done.js');
4 require('./finally.js');
5 require('./es6-extensions.js');
6 require('./node-extensions.js');
7 require('./synchronous.js');
0 'use strict';
1
2 // This file contains then/promise specific extensions that are only useful
3 // for node.js interop
4
5 var Promise = require('./core.js');
6 var asap = require('asap');
7
8 module.exports = Promise;
9
10 /* Static Functions */
11
12 Promise.denodeify = function (fn, argumentCount) {
13 if (
14 typeof argumentCount === 'number' && argumentCount !== Infinity
15 ) {
16 return denodeifyWithCount(fn, argumentCount);
17 } else {
18 return denodeifyWithoutCount(fn);
19 }
20 };
21
22 var callbackFn = (
23 'function (err, res) {' +
24 'if (err) { rj(err); } else { rs(res); }' +
25 '}'
26 );
27 function denodeifyWithCount(fn, argumentCount) {
28 var args = [];
29 for (var i = 0; i < argumentCount; i++) {
30 args.push('a' + i);
31 }
32 var body = [
33 'return function (' + args.join(',') + ') {',
34 'var self = this;',
35 'return new Promise(function (rs, rj) {',
36 'var res = fn.call(',
37 ['self'].concat(args).concat([callbackFn]).join(','),
38 ');',
39 'if (res &&',
40 '(typeof res === "object" || typeof res === "function") &&',
41 'typeof res.then === "function"',
42 ') {rs(res);}',
43 '});',
44 '};'
45 ].join('');
46 return Function(['Promise', 'fn'], body)(Promise, fn);
47 }
48 function denodeifyWithoutCount(fn) {
49 var fnLength = Math.max(fn.length - 1, 3);
50 var args = [];
51 for (var i = 0; i < fnLength; i++) {
52 args.push('a' + i);
53 }
54 var body = [
55 'return function (' + args.join(',') + ') {',
56 'var self = this;',
57 'var args;',
58 'var argLength = arguments.length;',
59 'if (arguments.length > ' + fnLength + ') {',
60 'args = new Array(arguments.length + 1);',
61 'for (var i = 0; i < arguments.length; i++) {',
62 'args[i] = arguments[i];',
63 '}',
64 '}',
65 'return new Promise(function (rs, rj) {',
66 'var cb = ' + callbackFn + ';',
67 'var res;',
68 'switch (argLength) {',
69 args.concat(['extra']).map(function (_, index) {
70 return (
71 'case ' + (index) + ':' +
72 'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' +
73 'break;'
74 );
75 }).join(''),
76 'default:',
77 'args[argLength] = cb;',
78 'res = fn.apply(self, args);',
79 '}',
80
81 'if (res &&',
82 '(typeof res === "object" || typeof res === "function") &&',
83 'typeof res.then === "function"',
84 ') {rs(res);}',
85 '});',
86 '};'
87 ].join('');
88
89 return Function(
90 ['Promise', 'fn'],
91 body
92 )(Promise, fn);
93 }
94
95 Promise.nodeify = function (fn) {
96 return function () {
97 var args = Array.prototype.slice.call(arguments);
98 var callback =
99 typeof args[args.length - 1] === 'function' ? args.pop() : null;
100 var ctx = this;
101 try {
102 return fn.apply(this, arguments).nodeify(callback, ctx);
103 } catch (ex) {
104 if (callback === null || typeof callback == 'undefined') {
105 return new Promise(function (resolve, reject) {
106 reject(ex);
107 });
108 } else {
109 asap(function () {
110 callback.call(ctx, ex);
111 })
112 }
113 }
114 }
115 };
116
117 Promise.prototype.nodeify = function (callback, ctx) {
118 if (typeof callback != 'function') return this;
119
120 this.then(function (value) {
121 asap(function () {
122 callback.call(ctx, null, value);
123 });
124 }, function (err) {
125 asap(function () {
126 callback.call(ctx, err);
127 });
128 });
129 };
0 'use strict';
1
2 var Promise = require('./core');
3
4 var DEFAULT_WHITELIST = [
5 ReferenceError,
6 TypeError,
7 RangeError
8 ];
9
10 var enabled = false;
11 exports.disable = disable;
12 function disable() {
13 enabled = false;
14 Promise._onHandle = null;
15 Promise._onReject = null;
16 }
17
18 exports.enable = enable;
19 function enable(options) {
20 options = options || {};
21 if (enabled) disable();
22 enabled = true;
23 var id = 0;
24 var displayId = 0;
25 var rejections = {};
26 Promise._onHandle = function (promise) {
27 if (
28 promise._state === 2 && // IS REJECTED
29 rejections[promise._rejectionId]
30 ) {
31 if (rejections[promise._rejectionId].logged) {
32 onHandled(promise._rejectionId);
33 } else {
34 clearTimeout(rejections[promise._rejectionId].timeout);
35 }
36 delete rejections[promise._rejectionId];
37 }
38 };
39 Promise._onReject = function (promise, err) {
40 if (promise._deferredState === 0) { // not yet handled
41 promise._rejectionId = id++;
42 rejections[promise._rejectionId] = {
43 displayId: null,
44 error: err,
45 timeout: setTimeout(
46 onUnhandled.bind(null, promise._rejectionId),
47 // For reference errors and type errors, this almost always
48 // means the programmer made a mistake, so log them after just
49 // 100ms
50 // otherwise, wait 2 seconds to see if they get handled
51 matchWhitelist(err, DEFAULT_WHITELIST)
52 ? 100
53 : 2000
54 ),
55 logged: false
56 };
57 }
58 };
59 function onUnhandled(id) {
60 if (
61 options.allRejections ||
62 matchWhitelist(
63 rejections[id].error,
64 options.whitelist || DEFAULT_WHITELIST
65 )
66 ) {
67 rejections[id].displayId = displayId++;
68 if (options.onUnhandled) {
69 rejections[id].logged = true;
70 options.onUnhandled(
71 rejections[id].displayId,
72 rejections[id].error
73 );
74 } else {
75 rejections[id].logged = true;
76 logError(
77 rejections[id].displayId,
78 rejections[id].error
79 );
80 }
81 }
82 }
83 function onHandled(id) {
84 if (rejections[id].logged) {
85 if (options.onHandled) {
86 options.onHandled(rejections[id].displayId, rejections[id].error);
87 } else if (!rejections[id].onUnhandled) {
88 console.warn(
89 'Promise Rejection Handled (id: ' + rejections[id].displayId + '):'
90 );
91 console.warn(
92 ' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id ' +
93 rejections[id].displayId + '.'
94 );
95 }
96 }
97 }
98 }
99
100 function logError(id, error) {
101 console.warn('Possible Unhandled Promise Rejection (id: ' + id + '):');
102 var errStr = (error && (error.stack || error)) + '';
103 errStr.split('\n').forEach(function (line) {
104 console.warn(' ' + line);
105 });
106 }
107
108 function matchWhitelist(error, list) {
109 return list.some(function (cls) {
110 return error instanceof cls;
111 });
112 }
0 'use strict';
1
2 var Promise = require('./core.js');
3
4 module.exports = Promise;
5 Promise.enableSynchronous = function () {
6 Promise.prototype.isPending = function() {
7 return this.getState() == 0;
8 };
9
10 Promise.prototype.isFulfilled = function() {
11 return this.getState() == 1;
12 };
13
14 Promise.prototype.isRejected = function() {
15 return this.getState() == 2;
16 };
17
18 Promise.prototype.getValue = function () {
19 if (this._state === 3) {
20 return this._value.getValue();
21 }
22
23 if (!this.isFulfilled()) {
24 throw new Error('Cannot get a value of an unfulfilled promise.');
25 }
26
27 return this._value;
28 };
29
30 Promise.prototype.getReason = function () {
31 if (this._state === 3) {
32 return this._value.getReason();
33 }
34
35 if (!this.isRejected()) {
36 throw new Error('Cannot get a rejection reason of a non-rejected promise.');
37 }
38
39 return this._value;
40 };
41
42 Promise.prototype.getState = function () {
43 if (this._state === 3) {
44 return this._value.getState();
45 }
46 if (this._state === -1 || this._state === -2) {
47 return 0;
48 }
49
50 return this._state;
51 };
52 };
53
54 Promise.disableSynchronous = function() {
55 Promise.prototype.isPending = undefined;
56 Promise.prototype.isFulfilled = undefined;
57 Promise.prototype.isRejected = undefined;
58 Promise.prototype.getValue = undefined;
59 Promise.prototype.getReason = undefined;
60 Promise.prototype.getState = undefined;
61 };
5454 done()
5555 })
5656 })
57 it('resolves correctly when the wrapped function returns a promise anyway', function (done) {
58 function wrap(val, key, callback) {
59 return new Promise(function(resolve, reject) {
60 resolve({val: val, key: key})
61 })
62 }
63 var pwrap = Promise.denodeify(wrap)
64 pwrap(sentinel, 'foo')
65 .then(function (wrapper) {
66 assert(wrapper.val === sentinel)
67 assert(wrapper.key === 'foo')
68 done()
69 })
70 })
5771 })
5872 describe('Promise.nodeify(fn)', function () {
5973 it('converts a promise returning function into a callback function', function (done) {
99113 assert(res === 3)
100114 done()
101115 })
116 })
117 it('passes through the `this` argument', function (done) {
118 var ctx = {}
119 var add = Promise.nodeify(function (a, b) {
120 return Promise.resolve(a)
121 .then(function (a) {
122 return a + b
123 })
124 })
125 add.call(ctx, 1, 2, function (err, res) {
126 assert(res === 3)
127 assert(this === ctx)
128 done()
129 })
102130 })
103131 })
104132 describe('Promise.all(...)', function () {
129157 })
130158 describe('of promises', function () {
131159 it('returns a promise for an array containing the fulfilled values', function (done) {
132 var res = Promise.all([A, B, C])
160 var d = {}
161 var resolveD
162 var res = Promise.all([A, B, C, new Promise(function (resolve) { resolveD = resolve })])
133163 assert(res instanceof Promise)
134164 res.then(function (res) {
135165 assert(Array.isArray(res))
136166 assert(res[0] === a)
137167 assert(res[1] === b)
138168 assert(res[2] === c)
139 })
140 .nodeify(done)
169 assert(res[3] === d)
170 })
171 .nodeify(done)
172 resolveD(d)
141173 })
142174 })
143175 describe('of mixed values', function () {
166198 .nodeify(done)
167199 })
168200 })
201 describe('containing at least one eventually rejected promise', function () {
202 it('rejects the resulting promise', function (done) {
203 var rejectB
204 var rejected = new Promise(function (resolve, reject) { rejectB = reject })
205 var res = Promise.all([A, rejected, C])
206 assert(res instanceof Promise)
207 res.then(function (res) {
208 throw new Error('Should be rejected')
209 },
210 function (err) {
211 assert(err === rejection)
212 })
213 .nodeify(done)
214 rejectB(rejection)
215 })
216 })
217 describe('with a promise that resolves twice', function () {
218 it('still waits for all the other promises', function (done) {
219 var fakePromise = {then: function (onFulfilled) { onFulfilled(1); onFulfilled(2) }}
220 var eventuallyRejected = {then: function (_, onRejected) { this.onRejected = onRejected }}
221 var res = Promise.all([fakePromise, eventuallyRejected])
222 assert(res instanceof Promise)
223 res.then(function (res) {
224 throw new Error('Should be rejected')
225 },
226 function (err) {
227 assert(err === rejection)
228 })
229 .nodeify(done)
230 eventuallyRejected.onRejected(rejection);
231 })
232 })
233 describe('when given a foreign promise', function () {
234 it('should provide the correct value of `this`', function (done) {
235 var p = {then: function (onFulfilled) { onFulfilled({self: this}); }};
236 Promise.all([p]).then(function (results) {
237 assert(p === results[0].self);
238 }).nodeify(done);
239 });
240 });
169241 })
170242 })
171243
173245 it.skip('behaves like then except for not returning anything', function () {
174246 //todo
175247 })
176 it.skip('rethrows unhandled rejections', function () {
177 //todo
248
249 it ('rethrows unhandled rejections', function (done) {
250 var originalTimeout = global.setTimeout
251
252 global.setTimeout = function(callback) {
253 try {
254 callback()
255 } catch (x) {
256 assert(x.message === 'It worked')
257 global.setTimeout = originalTimeout
258 return done()
259 }
260 done(new Error('Callback should have thrown an exception'))
261 }
262
263 Promise.resolve().done(function() {
264 throw new Error('It worked')
265 })
178266 })
179267 })
180268 describe('promise.nodeify(callback)', function () {
219307 done()
220308 })
221309 })
310 it('accepts a `context` argument', function (done) {
311 var ctx = {}
312 function add(a, b, callback) {
313 return Promise.resolve(a)
314 .then(function (a) {
315 return a + b
316 })
317 .nodeify(callback, ctx)
318 }
319 add(1, 2, function (err, res) {
320 assert(res === 3)
321 assert(this === ctx)
322 done()
323 })
324 })
325 })
326
327 describe('inheritance', function () {
328 it('allows its prototype methods to act upon foreign constructors', function () {
329 function Awesome(fn) {
330 if (!(this instanceof Awesome)) return new Awesome(fn)
331 Promise.call(this, fn)
332 }
333 Awesome.prototype = Object.create(Promise.prototype)
334 Awesome.prototype.constructor = Awesome
335
336 var awesome = new Awesome(function () {})
337
338 assert(awesome.constructor === Awesome)
339 assert(awesome.then(function () {}).constructor === Awesome)
340 })
222341 })
223342 })
0 'use strict';
1
2 var assert = require('assert')
3 var Promise = require('../')
4
5 var i = 0
6 var sampleA, sampleB
7
8 function next() {
9 return new Promise(function (resolve) {
10 i++
11 /*
12 if (i % 100000 === 0) {
13 global.gc()
14 console.dir(process.memoryUsage())
15 }
16 */
17 if (i === 100000 && typeof global.gc === 'function') {
18 global.gc()
19 sampleA = process.memoryUsage()
20 }
21 if (i > 100000 * 10) {
22 if (typeof global.gc === 'function') {
23 global.gc()
24 sampleB = process.memoryUsage()
25 console.log('Memory usage at start:');
26 console.dir(sampleA)
27 console.log('Memory usage at end:');
28 console.dir(sampleB)
29 assert(sampleA.heapUsed * 1.2 > sampleB.heapUsed, 'heapUsed should not grow by more than 20%')
30 }
31 } else {
32 setImmediate(resolve)
33 }
34 }).then(next)
35 }
36
37 if (typeof global.gc !== 'function') {
38 console.warn('You must run with --expose-gc to test for memory leak.')
39 }
40 next().done()
0 'use strict';
1
2 var assert = require('assert');
3 var Promise = require('../');
4
5 describe('nested promises', function () {
6 it('does not result in any wierd behaviour - 1', function (done) {
7 var resolveA, resolveB, resolveC;
8 var A = new Promise(function (resolve, reject) {
9 resolveA = resolve;
10 });
11 var B = new Promise(function (resolve, reject) {
12 resolveB = resolve;
13 });
14 var C = new Promise(function (resolve, reject) {
15 resolveC = resolve;
16 });
17 resolveA(B);
18 resolveB(C);
19 resolveC('foo');
20 A.done(function (result) {
21 assert(result === 'foo');
22 done();
23 });
24 });
25 it('does not result in any wierd behaviour - 2', function (done) {
26 var resolveA, resolveB, resolveC, resolveD;
27 var A = new Promise(function (resolve, reject) {
28 resolveA = resolve;
29 });
30 var B = new Promise(function (resolve, reject) {
31 resolveB = resolve;
32 });
33 var C = new Promise(function (resolve, reject) {
34 resolveC = resolve;
35 });
36 var D = new Promise(function (resolve, reject) {
37 resolveD = resolve;
38 });
39 var Athen = A.then, Bthen = B.then, Cthen = C.then, Dthen = D.then;
40 resolveA(B);
41 resolveB(C);
42 resolveC(D);
43 resolveD('foo');
44 A.done(function (result) {
45 assert(result === 'foo');
46 done();
47 });
48 });
49 it('does not result in any wierd behaviour - 2', function (done) {
50 var promises = [];
51 var resolveFns = [];
52 for (var i = 0; i < 100; i++) {
53 promises.push(new Promise(function (resolve) {
54 resolveFns.push(resolve);
55 }));
56 }
57 for (var i = 0; i < 99; i++) {
58 resolveFns[i](promises[i + 1]);
59 }
60 resolveFns[99]('foo');
61 promises[0].done(function (result) {
62 assert(result === 'foo');
63 done();
64 });
65 });
66 });
0 'use strict';
1
2 var assert = require('assert');
3 var Promise = require('../');
4 var tracking = require('../lib/rejection-tracking');
5
6 describe('unhandled rejections', function () {
7 it('tracks rejected promises', function (done) {
8 this.timeout(300);
9 var calls = [], promise;
10 tracking.enable({
11 onUnhandled: function (id, err) {
12 calls.push(['unhandled', id, err]);
13 promise.done(null, function (err) {
14 assert.deepEqual(calls, [
15 ['unhandled', 0, err],
16 ['handled', 0, err]
17 ]);
18 done();
19 });
20 },
21 onHandled: function (id, err) {
22 calls.push(['handled', id, err]);
23 }
24 });
25 promise = Promise.reject(new TypeError('A fake type error'));
26 })
27 it('tracks rejected promises', function (done) {
28 this.timeout(2200);
29 var calls = [], promise;
30 tracking.enable({
31 allRejections: true,
32 onUnhandled: function (id, err) {
33 calls.push(['unhandled', id, err]);
34 promise.done(null, function (err) {
35 assert.deepEqual(calls, [
36 ['unhandled', 0, err],
37 ['handled', 0, err]
38 ]);
39 done();
40 });
41 },
42 onHandled: function (id, err) {
43 calls.push(['handled', id, err]);
44 }
45 });
46 promise = Promise.reject({});
47 })
48 it('tracks rejected promises', function (done) {
49 this.timeout(500);
50 var calls = [], promise;
51 tracking.enable({
52 onUnhandled: function (id, err) {
53 done(new Error('Expected exception to be handled in time'));
54 },
55 onHandled: function (id, err) {
56 }
57 });
58 promise = Promise.reject(new TypeError('A fake type error'));
59 var isDone = false;
60 setTimeout(function () {
61 promise.done(null, function (err) {
62 // ignore
63 isDone = true;
64 });
65 }, 50);
66 setTimeout(function () {
67 assert(isDone);
68 done();
69 }, 400);
70 })
71 it('tracks rejected promises', function (done) {
72 this.timeout(2300);
73 var warn = console.warn;
74 var warnings = [];
75 console.warn = function (str) {
76 warnings.push(str);
77 };
78 var expectedWarnings = [
79 'Possible Unhandled Promise Rejection (id: 0):',
80 ' my',
81 ' multi',
82 ' line',
83 ' error',
84 'Promise Rejection Handled (id: 0):',
85 ' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id 0.'
86 ];
87 tracking.enable({allRejections: true});
88 var promise = Promise.reject('my\nmulti\nline\nerror');
89 setTimeout(function () {
90 promise.done(null, function (err) {
91 console.warn = warn;
92 assert.deepEqual(warnings, expectedWarnings);
93 done();
94 });
95 }, 2100);
96 })
97 })
3131 })
3232 })
3333 describe('if resolver is a function', function () {
34 it('must be called with the promise\'s resolver arguments', function () {
34 it('must be called with the promise\'s resolver arguments', function (done) {
3535 new Promise(function (resolve, reject) {
3636 assert(typeof resolve === 'function')
3737 assert(typeof reject === 'function')
157157 })
158158 })
159159 describe('otherwise', function () {
160 it('is rejected with e as the rejection reason', function () {
160 it('is rejected with e as the rejection reason', function (done) {
161161 new Promise(function (resolve, reject) {
162162 throw sentinel
163163 })
0 var assert = require('better-assert');
1 var Promise = require('../');
2
3 describe('synchronous-inspection-tests', function () {
4 it('cannot synchronously inspect before enabling synchronous inspection', function(done) {
5 var finished = null;
6 var fulfilledPromise = new Promise(function(resolve, reject) {
7 setTimeout(function() {
8 resolve();
9 }, 10);
10 });
11 var rejectedPromise = new Promise(function(resolve, reject) {
12 setTimeout(function() {
13 reject();
14 }, 10);
15 });
16
17 assert(fulfilledPromise.getValue == undefined);
18 assert(fulfilledPromise.getReason == undefined);
19 assert(fulfilledPromise.isFulfilled == undefined);
20 assert(fulfilledPromise.isPending == undefined);
21 assert(fulfilledPromise.isRejected == undefined);
22
23 assert(rejectedPromise.getValue == undefined);
24 assert(rejectedPromise.getReason == undefined);
25 assert(rejectedPromise.isFulfilled == undefined);
26 assert(rejectedPromise.isPending == undefined);
27 assert(rejectedPromise.isRejected == undefined);
28
29 setTimeout(function() {
30 assert(fulfilledPromise.getValue == undefined);
31 assert(fulfilledPromise.getReason == undefined);
32 assert(fulfilledPromise.isFulfilled == undefined);
33 assert(fulfilledPromise.isPending == undefined);
34 assert(fulfilledPromise.isRejected == undefined);
35
36 assert(rejectedPromise.getValue == undefined);
37 assert(rejectedPromise.getReason == undefined);
38 assert(rejectedPromise.isFulfilled == undefined);
39 assert(rejectedPromise.isPending == undefined);
40 assert(rejectedPromise.isRejected == undefined);
41
42 done()
43 }, 30);
44
45 });
46
47 it('can poll a promise to see if it is resolved', function (done) {
48 Promise.enableSynchronous();
49 var finished = null;
50 var fulfilledPromise = new Promise(function(resolve, reject) {
51 var interval = setInterval(function() {
52 if (finished !== null) {
53 clearTimeout(interval);
54
55 if (finished) {
56 resolve(true);
57 }
58 else {
59 reject(false);
60 }
61 }
62 }, 10);
63 });
64
65 assert(fulfilledPromise.getState() === 0);
66 assert(fulfilledPromise.isPending());
67 assert(!fulfilledPromise.isFulfilled());
68 assert(!fulfilledPromise.isRejected());
69
70 finished = true;
71
72 setTimeout(function () {
73 assert(fulfilledPromise.getState() === 1);
74 assert(fulfilledPromise.isFulfilled());
75 assert(!fulfilledPromise.isRejected());
76 assert(fulfilledPromise.getValue());
77 assert(!fulfilledPromise.isPending());
78
79 done();
80 }, 30);
81 });
82
83 it('can poll a promise to see if it is rejected', function (done) {
84 Promise.enableSynchronous();
85 var finished = null;
86 var fulfilledPromise = new Promise(function(resolve, reject) {
87 var interval = setInterval(function() {
88 if (finished !== null) {
89 clearTimeout(interval);
90
91 if (finished) {
92 resolve(true);
93 }
94 else {
95 reject(false);
96 }
97 }
98 }, 10);
99 });
100
101 assert(fulfilledPromise.getState() === 0);
102 assert(fulfilledPromise.isPending());
103 assert(!fulfilledPromise.isFulfilled());
104 assert(!fulfilledPromise.isRejected());
105
106 finished = false;
107
108 setTimeout(function () {
109 assert(fulfilledPromise.getState() === 2);
110 assert(!fulfilledPromise.isFulfilled());
111 assert(fulfilledPromise.isRejected());
112 assert(!fulfilledPromise.getReason());
113 assert(!fulfilledPromise.isPending());
114
115 done();
116 }, 30);
117 });
118
119 it('will throw an error if getting a value of an unfulfilled promise', function (done) {
120 Promise.enableSynchronous();
121 var finished = null;
122 var fulfilledPromise = new Promise(function(resolve, reject) {
123 var interval = setInterval(function() {
124 if (finished !== null) {
125 clearTimeout(interval);
126
127 if (finished) {
128 resolve(true);
129 }
130 else {
131 reject(false);
132 }
133 }
134 }, 10);
135 });
136
137 assert(fulfilledPromise.isPending());
138 assert(!fulfilledPromise.isFulfilled());
139 assert(!fulfilledPromise.isRejected());
140
141 try {
142 fulfilledPromise.getValue();
143
144 assert(false);
145 }
146 catch (e) {
147 assert(true);
148 }
149
150 finished = false;
151
152 setTimeout(function () {
153 try {
154 fulfilledPromise.getValue();
155
156 assert(false);
157 }
158 catch (e) {
159 assert(true);
160 }
161
162 done();
163 }, 30);
164 });
165
166 it('will throw an error if getting a reason of a non-rejected promise', function (done) {
167 Promise.enableSynchronous();
168 var finished = null;
169 var fulfilledPromise = new Promise(function(resolve, reject) {
170 var interval = setInterval(function() {
171 if (finished !== null) {
172 clearTimeout(interval);
173
174 if (finished) {
175 resolve(true);
176 }
177 else {
178 reject(false);
179 }
180 }
181 }, 10);
182 });
183
184 assert(fulfilledPromise.isPending());
185 assert(!fulfilledPromise.isFulfilled());
186 assert(!fulfilledPromise.isRejected());
187
188 try {
189 fulfilledPromise.getReason();
190
191 assert(false);
192 }
193 catch (e) {
194 assert(true);
195 }
196
197 finished = true;
198
199 setTimeout(function () {
200 try {
201 fulfilledPromise.getReason();
202
203 assert(false);
204 }
205 catch (e) {
206 assert(true);
207 }
208
209 done()
210 }, 30);
211 });
212
213 it('can disable synchronous inspection', function() {
214 Promise.enableSynchronous();
215 var testPromise = Promise.resolve('someValue');
216 assert(testPromise.getValue() == 'someValue');
217 Promise.disableSynchronous();
218 assert(testPromise.getValue == undefined);
219 });
220
221 it('can synchronously poll a resolving promise chain', function (done) {
222 Promise.enableSynchronous();
223 var fulfilledPromise = new Promise(function(resolve, reject) {
224 var interval = setTimeout(function() {
225 resolve(Promise.resolve(true));
226 }, 10);
227 });
228
229 assert(fulfilledPromise.getState() === 0);
230 assert(fulfilledPromise.isPending());
231 assert(!fulfilledPromise.isFulfilled());
232 assert(!fulfilledPromise.isRejected());
233
234 setTimeout(function() {
235 assert(fulfilledPromise.getState() === 1);
236 assert(fulfilledPromise.isFulfilled());
237 assert(!fulfilledPromise.isRejected());
238 assert(fulfilledPromise.getValue());
239 assert(!fulfilledPromise.isPending());
240
241 done();
242 }, 30);
243 });
244
245 it('can synchronously poll a rejecting promise chain', function(done) {
246 Promise.enableSynchronous();
247 var rejectedPromise = new Promise(function(resolve, reject) {
248 setTimeout(function() {
249 resolve(Promise.reject(false));
250 }, 10);
251 });
252
253 assert(rejectedPromise.getState() === 0);
254 assert(rejectedPromise.isPending());
255 assert(!rejectedPromise.isFulfilled());
256 assert(!rejectedPromise.isRejected());
257
258 setTimeout(function() {
259 assert(rejectedPromise.getState() === 2);
260 assert(!rejectedPromise.isFulfilled());
261 assert(rejectedPromise.isRejected());
262 assert(!rejectedPromise.getReason());
263 assert(!rejectedPromise.isPending());
264
265 done();
266 }, 30);
267 });
268 });