21 |
22 |
23 |
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013-2017 Petka Antonov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/docs/api/timeouterror.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: api
3 | id: timeouterror
4 | title: TimeoutError
5 | ---
6 |
7 |
8 | [← Back To API Reference](/docs/api-reference.html)
9 |
10 | ##TimeoutError
11 |
12 | ```js
13 | new TimeoutError(String message) -> TimeoutError
14 | ```
15 |
16 |
17 | Signals that an operation has timed out. Used as a custom cancellation reason in [`.timeout`](.).
18 |
10 | ##.reduce
11 |
12 | ```js
13 | .reduce(
14 | function(any accumulator, any item, int index, int length) reducer,
15 | [any initialValue]
16 | ) -> Promise
17 | ```
18 |
19 | Same as [Promise.reduce(this, reducer, initialValue)](.).
20 |
21 |
22 |
23 |
34 |
35 |
--------------------------------------------------------------------------------
/test/mocha/2.3.1.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var assert = require("assert");
4 |
5 | var adapter = global.adapter;
6 | var fulfilled = adapter.fulfilled;
7 | var rejected = adapter.rejected;
8 |
9 | var dummy = { dummy: "dummy" }; // we fulfill or reject with this when we don't intend to test against it
10 |
11 | describe("2.3.1: If `promise` and `x` refer to the same object, reject `promise` with a `TypeError' as the reason.",
12 | function () {
13 | specify("via return from a fulfilled promise", function (done) {
14 | var promise = fulfilled(dummy).then(function () {
15 | return promise;
16 | });
17 |
18 | promise.then(null, function (reason) {
19 | assert(reason instanceof adapter.TypeError);
20 | done();
21 | });
22 | });
23 |
24 | specify("via return from a rejected promise", function (done) {
25 | var promise = rejected(dummy).then(null, function () {
26 | return promise;
27 | });
28 |
29 | promise.then(null, function (reason) {
30 | assert(reason instanceof adapter.TypeError);
31 | done();
32 | });
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/bench:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | ./build --release --no-debug
3 | benchmark=$1
4 | nodepath=${2:-node}
5 | shift 2;
6 | cwd=${PWD}
7 |
8 | trap 'cd "$cwd"' EXIT
9 |
10 | if [ "$benchmark" = "doxbee" ]; then
11 | cd "$cwd/benchmark"
12 | npm install
13 | echo "Doxbee sequential"
14 | $nodepath performance.js --n 10000 --t 1 ./doxbee-sequential/*.js --harmony "$@"
15 | exit 0
16 | elif [ "$benchmark" = "doxbee-errors" ]; then
17 | cd "$cwd/benchmark"
18 | npm install
19 | echo "Doxbee sequential with 10% errors"
20 | $nodepath performance.js --n 10000 --t 1 --e 0.1 ./doxbee-sequential-errors/*.js --harmony "$@"
21 | exit 0
22 | elif [ "$benchmark" = "parallel" ]; then
23 | cd "$cwd/benchmark"
24 | npm install
25 | echo "Madeup parallel"
26 | $nodepath performance.js --n 10000 --t 1 --p 25 ./madeup-parallel/*.js --harmony "$@"
27 | exit 0
28 | elif [ "$benchmark" = "analysis" ]; then
29 | cd "$cwd/benchmark"
30 | npm install
31 | echo "analysis"
32 | $nodepath performance.js --n 10000 --t 1 ./analysis/*.js --harmony "$@"
33 | exit 0
34 | else
35 | echo "Invalid benchmark name $benchmark"
36 | exit -1
37 | fi
38 |
--------------------------------------------------------------------------------
/benchmark/lib/fakes-ctx.js:
--------------------------------------------------------------------------------
1 | var timers = require('./timers-ctx');
2 |
3 | var fakemaker = require('./fakemaker');
4 |
5 | var f = {};
6 | f.dummy = function dummy(n) {
7 | return function dummy_n() {
8 | var cb = arguments[n - 1],
9 | ctx = arguments[n];
10 | //console.log(cb, ctx);
11 |
12 | timers.setTimeout(cb, ctx, global.asyncTime || 100);
13 | }
14 | }
15 |
16 | // A throwing callback function
17 | f.dummyt = function dummyt(n) {
18 | return function dummy_throwing_n() {
19 | var cb = arguments[n - 1],
20 | ctx = arguments[n];
21 | if (global.testThrow)
22 | throw(new Error("Exception happened"));
23 | setTimeout(function throwTimeout() {
24 | if (global.testThrowAsync) {
25 | throw(new Error("Exception happened"));
26 | } else if (global.testError) {
27 | return cb.call(ctx, new Error("Error happened"));
28 | }
29 | else cb.call(ctx);
30 | }, global.asyncTime || 100);
31 | }
32 | }
33 |
34 |
35 |
36 |
37 | fakemaker(f.dummy, f.dummyt, function wrap_identity(f) { return f; });
38 |
39 |
40 |
--------------------------------------------------------------------------------
/docs/docs/api/cancel.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: api
3 | id: cancel
4 | title: .cancel
5 | ---
6 |
7 |
8 | [← Back To API Reference](/docs/api-reference.html)
9 |
10 | ##.cancel
11 |
12 | ```js
13 | .cancel() -> undefined
14 | ```
15 |
16 | Cancel this promise. Will not do anything if this promise is already settled or if the [Cancellation](.) feature has not been enabled. See [Cancellation](.) for how to use cancellation.
17 |
18 |
19 |
10 | ##CancellationError
11 |
12 | ```js
13 | new CancellationError(String message) -> CancellationError
14 | ```
15 |
16 |
17 | Signals that an operation has been aborted or cancelled. The default reason used by [`.cancel`](.).
18 |
10 | ##Promise.any
11 |
12 | ```js
13 | Promise.any(Iterable|Promise> input) -> Promise
14 | ```
15 |
16 | Like [Promise.some](.), with 1 as `count`. However, if the promise fulfills, the fulfillment value is not an array of 1 but the value directly.
17 |
18 |
19 |
20 |
31 |
--------------------------------------------------------------------------------
/test/mocha/late_buffer_safety.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var assert = require("assert");
4 | var testUtils = require("./helpers/util.js");
5 | var isNodeJS = testUtils.isNodeJS;
6 |
7 | function async(cb){
8 | return Promise.resolve().nodeify(cb);
9 | }
10 |
11 | if (isNodeJS) {
12 | describe("Late buffer", function() {
13 | specify("shouldn't stop at first error but continue consumption until everything is consumed", function(){
14 | var length = 10;
15 | var l = length;
16 | var a = 0;
17 | while (l--){
18 | async(function(){
19 | throw (a++);
20 | });
21 | }
22 | var errs = [];
23 | return testUtils.awaitGlobalException(function(e) {
24 | errs.push(e);
25 | if (errs.length === length) {
26 | var a = [];
27 | for (var i = 0, len = length; i < len; ++i) {
28 | a[i] = i;
29 | }
30 | assert.deepEqual(a, errs);
31 | } else {
32 | return false;
33 | }
34 | });
35 | });
36 | });
37 | }
38 |
--------------------------------------------------------------------------------
/benchmark/lib/fakesSJS-src.sjs:
--------------------------------------------------------------------------------
1 | var f = require('./dummy.js');
2 |
3 | var makefakes = require('./fakemaker.js');
4 |
5 | function wrap(f) {
6 | return function(x, y) {
7 | waitfor(var err, val) {
8 | f(x, y, resume);
9 | }
10 | if (err) throw err;
11 | return val;
12 | };
13 | }
14 |
15 | function dummySJS0() {
16 | var inner = f.dummy(1);
17 | return function() {
18 | waitfor (var err, val) {
19 | inner(resume);
20 | }
21 | if (err) throw err;
22 | return val;
23 | }
24 | }
25 |
26 | function dummySJS1() {
27 | var inner = f.dummy(2);
28 | return function(x) {
29 | waitfor (var err, val) {
30 | inner(x, resume);
31 | }
32 | if (err) throw err;
33 | return val;
34 | }
35 | }
36 |
37 | function dummySJS(n) {
38 | if (n === 1) return dummySJS0();
39 | if (n === 2) return dummySJS1();
40 | }
41 |
42 | function dummytSJS(n) {
43 | var inner = f.dummyt(n);
44 | return function() {
45 | waitfor(var err, val) {
46 | var args = Array.prototype.slice.apply(arguments);
47 | args.push(resume);
48 | inner.apply(this, args);
49 | }
50 |
51 | if (err) throw err;
52 | return val;
53 | }
54 | }
55 |
56 | makefakes(dummySJS, dummytSJS, wrap, global);
57 |
--------------------------------------------------------------------------------
/docs/docs/api/then.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: api
3 | id: then
4 | title: .then
5 | ---
6 |
7 |
8 | [← Back To API Reference](/docs/api-reference.html)
9 |
10 | ##.then
11 |
12 | ```js
13 | .then(
14 | [function(any value) fulfilledHandler],
15 | [function(any error) rejectedHandler]
16 | ) -> Promise
17 | ```
18 |
19 |
20 | [Promises/A+ `.then`](http://promises-aplus.github.io/promises-spec/). If you are new to promises, see the [Beginner's Guide]({{ "/docs/beginners-guide.html" | prepend: site.baseurl }}).
21 |
22 |
23 |
24 |
35 |
--------------------------------------------------------------------------------
/docs/docs/getting-started.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: getting-started
3 | title: Getting Started
4 | redirect_from: "/index.html"
5 | redirect_from: "/docs/index.html"
6 | ---
7 |
8 | [getting-started](unfinished-article)
9 |
10 | ## Node.js
11 |
12 | npm install bluebird
13 |
14 | Then:
15 |
16 | ```js
17 | var Promise = require("bluebird");
18 | ```
19 |
20 | ## Browsers
21 |
22 | (See also [Installation](install.html).)
23 |
24 | There are many ways to use bluebird in browsers:
25 |
26 | - Direct downloads
27 | - Full build [bluebird.js](https://cdn.jsdelivr.net/bluebird/latest/bluebird.js)
28 | - Full build minified [bluebird.min.js](https://cdn.jsdelivr.net/bluebird/latest/bluebird.min.js)
29 | - Core build [bluebird.core.js](https://cdn.jsdelivr.net/bluebird/latest/bluebird.core.js)
30 | - Core build minified [bluebird.core.min.js](https://cdn.jsdelivr.net/bluebird/latest/bluebird.core.min.js)
31 | - You may use browserify on the main export
32 | - You may use the [bower](http://bower.io) package.
33 |
34 | When using script tags the global variables `Promise` and `P` (alias for `Promise`) become available. Bluebird runs on a wide variety of browsers including older versions. We'd like to thank BrowserStack for giving us a free account which helps us test that.
35 |
--------------------------------------------------------------------------------
/docs/docs/api/value.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: api
3 | id: value
4 | title: .value
5 | ---
6 |
7 |
8 | [← Back To API Reference](/docs/api-reference.html)
9 |
10 | ##.value
11 |
12 | ```js
13 | .value() -> any
14 | ```
15 |
16 |
17 | Get the fulfillment value of this promise. Throws an error if the promise isn't fulfilled - it is a bug to call this method on an unfulfilled promise.
18 |
19 | You should check if this promise is [.isFulfilled()](.) in code paths where it's not guaranteed that this promise is fulfilled.
20 |
10 | ##.reason
11 |
12 | ```js
13 | .reason() -> any
14 | ```
15 |
16 |
17 | Get the rejection reason of this promise. Throws an error if the promise isn't rejected - it is a bug to call this method on an unrejected promise.
18 |
19 | You should check if this promise is [.isRejected()](.) in code paths where it's guaranteed that this promise is rejected.
20 |
21 |
22 |
10 | ##.done
11 |
12 | ```js
13 | .done(
14 | [function(any value) fulfilledHandler],
15 | [function(any error) rejectedHandler]
16 | ) -> undefined
17 | ```
18 |
19 |
20 | Like [`.then`](.), but any unhandled rejection that ends up here will crash the process (in node) or be thrown as an error (in browsers). The use of this method is heavily discouraged and it only exists for historical reasons.
21 |
22 |
23 |
10 | ##.catchReturn
11 |
12 | ```js
13 | .catchReturn(
14 | [class ErrorClass|function(any error) predicate],
15 | any value
16 | ) -> Promise
17 | ```
18 |
19 | Convenience method for:
20 |
21 | ```js
22 | .catch(function() {
23 | return value;
24 | });
25 | ```
26 | You may optionally prepend one predicate function or ErrorClass to pattern match the error (the generic [.catch](.) methods accepts multiple)
27 |
28 | Same limitations regarding to the binding time of `value` to apply as with [`.return`](.).
29 |
30 |
31 |
32 |
43 |
--------------------------------------------------------------------------------
/docs/docs/support.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: support
3 | title: Support
4 | ---
5 |
6 | Depending on the nature of your problem there are a few possible ways of getting help with your problem.
7 |
8 | ###Stack Overflow
9 |
10 | Stack Overflow has an active community answering questions on both the [bluebird](http://stackoverflow.com/questions/tagged/bluebird) and [promise](http://stackoverflow.com/questions/tagged/promise) tags. If you are unfamiliar with Stack Overflow, do review [the asking guidelines](http://stackoverflow.com/help/asking) before asking a new question there.
11 |
12 | ###Google Groups mailing list
13 |
14 | The [bluebird-js@googlegroups.com](https://groups.google.com/forum/#!forum/bluebird-js) mailing list is the best place to ask any question that cannot be easily fit in the stack overflow question format.
15 |
16 | ###IRC
17 |
18 | You can usually get fast answers on the freenode.net channels [#bluebird](irc://chat.freenode.net/bluebird) and [#promises](irc://chat.freenode.net/promises).
19 |
20 | ###Gitter
21 |
22 | If you are not comfortable using IRC you can also join the [bluebird gitter chat](https://gitter.im/petkaantonov/bluebird)
23 |
24 | ###Github issue tracker
25 |
26 | If you feel that your problem is caused by a bug or a missing feature that should be added, you should use the [Github issue tracker](https://github.com/petkaantonov/bluebird/issues/) to report it. However in any other case the issue tracker is not the appropriate channel.
27 |
--------------------------------------------------------------------------------
/docs/docs/api/collections.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: api
3 | id: collections
4 | title: Collections
5 | ---
6 |
7 |
8 | [← Back To API Reference](/docs/api-reference.html)
9 |
10 | ##Collections
11 |
12 | Methods of `Promise` instances and core static methods of the Promise class to deal with collections of promises or mixed promises and values.
13 |
14 | All collection methods have a static equivalent on the Promise object, e.g. `somePromise.map(...)...` is same as `Promise.map(somePromise, ...)...`,
15 | `somePromise.all` is same as [`Promise.all`](.) and so on.
16 |
17 | None of the collection methods modify the original input. Holes in arrays are treated as if they were defined with the value `undefined`.
18 |
19 |
20 |
21 |
32 |
--------------------------------------------------------------------------------
/benchmark/madeup-parallel/streamline-generators.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _streamline = typeof require === 'function' ? require('streamline-runtime/lib/generators/runtime') : Streamline.require('streamline-runtime/lib/generators/runtime');
4 |
5 | var _filename = '/Users/bruno/dev/bluebird/benchmark/madeup-parallel/streamline._js';
6 |
7 | var execWithin = _streamline.async(function* _$$execWithin$$(query, tx, _2) {
8 | {
9 | return yield _streamline.await(_filename, 5, query, 'execWithin', 1, null, false, [tx, true]);
10 | }
11 | }, 2, 3);
12 |
13 | require('../lib/fakes');
14 |
15 | // Futures work on streamlined function so we need to wrap execWithin
16 |
17 |
18 | module.exports = _streamline.async(function* _$$upload$$(stream, idOrPath, tag, _3) {
19 | {
20 | try {
21 | var queries = new Array(global.parallelQueries);
22 | var tx = db.begin();
23 |
24 | for (var i = 0, len = queries.length; i < len; ++i) {
25 | queries[i] = _streamline.future(_filename, 14, null, execWithin, 2, null, false, [FileVersion.insert({ index: i }), tx, false]);
26 | }
27 |
28 | for (var i = 0, len = queries.length; i < len; ++i) {
29 | yield _streamline.await(_filename, 18, queries, i, 0, null, false, [true]);
30 | }
31 |
32 | tx.commit();
33 | } catch (err) {
34 | tx.rollback();
35 | throw err;
36 | }
37 | }
38 | }, 3, 4);
--------------------------------------------------------------------------------
/benchmark/lib/fakesObservable.js:
--------------------------------------------------------------------------------
1 | var lifter, fromNodeCallback;
2 | if (global.useRx) {
3 | lifter = require("rx").Observable.fromNodeCallback;
4 | } else if (global.useBacon) {
5 | fromNodeCallback = require("baconjs").fromNodeCallback;
6 | } else if (global.useKefir) {
7 | fromNodeCallback = require("kefir").Kefir.fromNodeCallback;
8 | lifter = function(nodeFn) {
9 | return function() {
10 | var args = [].slice.call(arguments);
11 | function thunk(callback) {
12 | args.push(callback);
13 | nodeFn.apply(null, args);
14 | args.pop();
15 | }
16 | return fromNodeCallback(thunk);
17 | }
18 | };
19 | } else if (global.useHighland) {
20 | lifter = require("highland").wrapCallback;
21 | }
22 |
23 | if (!lifter) {
24 | lifter = function(nodeFn) {
25 | return function() {
26 | var args = [].slice.call(arguments);
27 | args.unshift(nodeFn);
28 | return fromNodeCallback.apply(undefined, args);
29 | };
30 | };
31 | }
32 |
33 | var f = require('./dummy');
34 |
35 | var makefakes = require('./fakemaker');
36 |
37 | // A function taking n values or promises and returning
38 | // a promise
39 | function dummyP(n) {
40 | return lifter(f.dummy(n));
41 | }
42 |
43 | // Throwing version of above
44 | function dummytP(n) {
45 | return lifter(f.dummyt(n));
46 | }
47 |
48 | makefakes(dummyP, dummytP, lifter);
49 |
--------------------------------------------------------------------------------
/docs/docs/api/operationalerror.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: api
3 | id: operationalerror
4 | title: OperationalError
5 | ---
6 |
7 |
8 | [← Back To API Reference](/docs/api-reference.html)
9 |
10 | ##OperationalError
11 |
12 | ```js
13 | new OperationalError(String message) -> OperationalError
14 | ```
15 |
16 |
17 | Represents an error is an explicit promise rejection as opposed to a thrown error. For example, if an error is errbacked by a callback API promisified through [`Promise.promisify`](.) or [`Promise.promisifyAll`](.)
18 | and is not a typed error, it will be converted to a `OperationalError` which has the original error in the `.cause` property.
19 |
20 | `OperationalError`s are caught in [`.error`](.) handlers.
21 |
10 | ##Built-in error types
11 |
12 | Bluebird includes a few built-in error types for common usage. All error types have the same identity across different copies of bluebird
13 | module so that pattern matching works in [`.catch`](.). All error types have a constructor taking a message string as their first argument, with that message
14 | becoming the `.message` property of the error object.
15 |
16 | By default the error types need to be referenced from the Promise constructor, e.g. to get a reference to [TimeoutError](.), do `var TimeoutError = Promise.TimeoutError`. However, for convenience you will probably want to just make the references global.
17 |
10 | ##Deferred migration
11 |
12 | Deferreds are deprecated in favor of the promise constructor. If you need deferreds for some reason, you can create them trivially using the constructor:
13 |
14 | ```js
15 | function defer() {
16 | var resolve, reject;
17 | var promise = new Promise(function() {
18 | resolve = arguments[0];
19 | reject = arguments[1];
20 | });
21 | return {
22 | resolve: resolve,
23 | reject: reject,
24 | promise: promise
25 | };
26 | }
27 | ```
28 |
29 | For old code that still uses deferred objects, see [the deprecated API docs ](//bluebirdjs.com/docs/deprecated-apis.html#promise-resolution).
30 |
31 |
32 |
33 |
44 |
45 |
--------------------------------------------------------------------------------
/src/nodeback.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var util = require("./util");
3 | var maybeWrapAsError = util.maybeWrapAsError;
4 | var errors = require("./errors");
5 | var OperationalError = errors.OperationalError;
6 | var es5 = require("./es5");
7 |
8 | function isUntypedError(obj) {
9 | return obj instanceof Error &&
10 | es5.getPrototypeOf(obj) === Error.prototype;
11 | }
12 |
13 | var rErrorKey = /^(?:name|message|stack|cause)$/;
14 | function wrapAsOperationalError(obj) {
15 | var ret;
16 | if (isUntypedError(obj)) {
17 | ret = new OperationalError(obj);
18 | ret.name = obj.name;
19 | ret.message = obj.message;
20 | ret.stack = obj.stack;
21 | var keys = es5.keys(obj);
22 | for (var i = 0; i < keys.length; ++i) {
23 | var key = keys[i];
24 | if (!rErrorKey.test(key)) {
25 | ret[key] = obj[key];
26 | }
27 | }
28 | return ret;
29 | }
30 | util.markAsOriginatingFromRejection(obj);
31 | return obj;
32 | }
33 |
34 | function nodebackForPromise(promise, multiArgs) {
35 | return function(err, value) {
36 | if (promise === null) return;
37 | if (err) {
38 | var wrapped = wrapAsOperationalError(maybeWrapAsError(err));
39 | promise._attachExtraTrace(wrapped);
40 | promise._reject(wrapped);
41 | } else if (!multiArgs) {
42 | promise._fulfill(value);
43 | } else {
44 | INLINE_SLICE(args, arguments, 1);
45 | promise._fulfill(args);
46 | }
47 | promise = null;
48 | };
49 | }
50 |
51 | module.exports = nodebackForPromise;
52 |
--------------------------------------------------------------------------------
/test/mocha/github36.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var assert = require("assert");
4 | var testUtils = require("./helpers/util.js");
5 |
6 |
7 | describe("github36", function(){
8 | specify("should work", function() {
9 | return new Promise(function(resolve, reject) {
10 | var called = 0;
11 | var donecalled = false;
12 | var _d = Promise.defer();
13 |
14 | _d.resolve()
15 |
16 | var f1 = function() {
17 | return _d.promise.then(function() {
18 | return true;
19 | })
20 | }
21 |
22 | var f2 = function() {
23 | var d1 = Promise.defer()
24 |
25 | setTimeout(function() {
26 | d1.resolve()
27 | }, 1)
28 |
29 | return d1.promise.then(function() {
30 | return _d.promise.then(function() {
31 | })
32 | });
33 | }
34 |
35 | var f3 = function() {
36 | called++;
37 | if (called > 15) {
38 | return resolve();
39 | }
40 | var promise = f1().then(function() {
41 | f2()
42 | .then(function() {
43 | f3()
44 | })
45 | })
46 |
47 | promise.lastly(function() {
48 | setTimeout(function() {
49 | f3()
50 | }, 1)
51 | })
52 |
53 | }
54 |
55 | f3();
56 | });
57 | });
58 | });
59 |
60 |
--------------------------------------------------------------------------------
/benchmark/doxbee-sequential-errors/streamline._js:
--------------------------------------------------------------------------------
1 | require('../lib/fakes');
2 |
3 | module.exports = function upload(stream, idOrPath, tag, _) {
4 | try {
5 | var blob = blobManager.create(account);
6 | var tx = db.begin();
7 | var blobId = blob.put(stream, _);
8 | var file = self.byUuidOrPath(idOrPath).get(_);
9 |
10 | var previousId = file ? file.version : null;
11 | var version = {
12 | userAccountId: userAccount.id,
13 | date: new Date(),
14 | blobId: blobId,
15 | creatorId: userAccount.id,
16 | previousId: previousId,
17 | };
18 | version.id = Version.createHash(version);
19 | Version.insert(version).execWithin(tx, _);
20 | triggerIntentionalError();
21 | if (!file) {
22 | var splitPath = idOrPath.split('/');
23 | var fileName = splitPath[splitPath.length - 1];
24 | file = {
25 | id: uuid.v1(),
26 | userAccountId: userAccount.id,
27 | name: fileName,
28 | version: version.id
29 | }
30 | var query = self.createQuery(idOrPath, file, _);
31 | query.execWithin(tx, _);
32 | triggerIntentionalError();
33 | }
34 | FileVersion.insert({fileId: file.id, versionId: version.id})
35 | .execWithin(tx, _);
36 | triggerIntentionalError();
37 | File.whereUpdate({id: file.id}, {version: version.id})
38 | .execWithin(tx, _);
39 | triggerIntentionalError();
40 | tx.commit();
41 | } catch (err) {
42 | tx.rollback();
43 | throw err;
44 | }
45 | };
--------------------------------------------------------------------------------
/test/mocha/2.2.1.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var adapter = global.adapter;
4 | var fulfilled = adapter.fulfilled;
5 | var rejected = adapter.rejected;
6 |
7 | var dummy = { dummy: "dummy" }; // we fulfill or reject with this when we don't intend to test against it
8 |
9 | describe("2.2.1: Both `onFulfilled` and `onRejected` are optional arguments.", function () {
10 | describe("2.2.1.1: If `onFulfilled` is not a function, it must be ignored.", function () {
11 | function testNonFunction(nonFunction, stringRepresentation) {
12 | specify("`onFulfilled` is " + stringRepresentation, function (done) {
13 | rejected(dummy).then(nonFunction, function () {
14 | done();
15 | });
16 | });
17 | }
18 |
19 | testNonFunction(undefined, "`undefined`");
20 | testNonFunction(null, "`null`");
21 | testNonFunction(false, "`false`");
22 | testNonFunction(5, "`5`");
23 | testNonFunction({}, "an object");
24 | });
25 |
26 | describe("2.2.1.2: If `onRejected` is not a function, it must be ignored.", function () {
27 | function testNonFunction(nonFunction, stringRepresentation) {
28 | specify("`onRejected` is " + stringRepresentation, function (done) {
29 | fulfilled(dummy).then(function () {
30 | done();
31 | }, nonFunction);
32 | });
33 | }
34 |
35 | testNonFunction(undefined, "`undefined`");
36 | testNonFunction(null, "`null`");
37 | testNonFunction(false, "`false`");
38 | testNonFunction(5, "`5`");
39 | testNonFunction({}, "an object");
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/test/mocha/3.2.1.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var adapter = global.adapter;
4 | var fulfilled = adapter.fulfilled;
5 | var rejected = adapter.rejected;
6 |
7 | var dummy = { dummy: "dummy" }; // we fulfill or reject with this when we don't intend to test against it
8 |
9 | describe("3.2.1: Both `onFulfilled` and `onRejected` are optional arguments.", function () {
10 | describe("3.2.1.1: If `onFulfilled` is not a function, it must be ignored.", function () {
11 | function testNonFunction(nonFunction, stringRepresentation) {
12 | specify("`onFulfilled` is " + stringRepresentation, function (done) {
13 | rejected(dummy).then(nonFunction, function () {
14 | done();
15 | });
16 | });
17 | }
18 |
19 | testNonFunction(undefined, "`undefined`");
20 | testNonFunction(null, "`null`");
21 | testNonFunction(false, "`false`");
22 | testNonFunction(5, "`5`");
23 | testNonFunction({}, "an object");
24 | });
25 |
26 | describe("3.2.1.2: If `onRejected` is not a function, it must be ignored.", function () {
27 | function testNonFunction(nonFunction, stringRepresentation) {
28 | specify("`onRejected` is " + stringRepresentation, function (done) {
29 | fulfilled(dummy).then(function () {
30 | done();
31 | }, nonFunction);
32 | });
33 | }
34 |
35 | testNonFunction(undefined, "`undefined`");
36 | testNonFunction(null, "`null`");
37 | testNonFunction(false, "`false`");
38 | testNonFunction(5, "`5`");
39 | testNonFunction({}, "an object");
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/docs/docs/api/get.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: api
3 | id: get
4 | title: .get
5 | ---
6 |
7 |
8 | [← Back To API Reference](/docs/api-reference.html)
9 |
10 | ##.get
11 |
12 | ```js
13 | .get(String propertyName|int index) -> Promise
14 | ```
15 |
16 |
17 | This is a convenience method for doing:
18 |
19 | ```js
20 | promise.then(function(obj) {
21 | return obj[propertyName];
22 | });
23 | ```
24 |
25 | For example:
26 |
27 | ```js
28 | db.query("...")
29 | .get(0)
30 | .then(function(firstRow) {
31 |
32 | });
33 | ```
34 |
35 | If `index` is negative, the indexed load will become `obj.length + index`. So that -1 can be used to read last item
36 | in the array, -2 to read the second last and so on. For example:
37 |
38 | ```js
39 | Promise.resolve([1,2,3]).get(-1).then(function(value) {
40 | console.log(value); // 3
41 | });
42 | ```
43 |
44 | If the `index` is still negative after `obj.length + index`, it will be clamped to 0.
45 |
10 | ##AggregateError
11 |
12 | ```js
13 | new AggregateError() extends Array -> AggregateError
14 | ```
15 |
16 |
17 | A collection of errors. `AggregateError` is an array-like object, with numeric indices and a `.length` property. It supports all generic array methods such as `.forEach` directly.
18 |
19 | `AggregateError`s are caught in [`.error`](.) handlers, even if the contained errors are not operational.
20 |
21 | [Promise.some](.) and [Promise.any](.) use `AggregateError` as rejection reason when they fail.
22 |
23 |
24 | Example:
25 |
26 | ```js
27 | //Assumes AggregateError has been made global
28 | var err = new AggregateError();
29 | err.push(new Error("first error"));
30 | err.push(new Error("second error"));
31 | throw err;
32 | ```
33 |
34 |
35 |
10 | ##Promise.delay
11 |
12 | ```js
13 | Promise.delay(
14 | int ms,
15 | [any|Promise value=undefined]
16 | ) -> Promise
17 | ```
18 |
19 |
20 | Returns a promise that will be resolved with `value` (or `undefined`) after given `ms` milliseconds. If `value` is a promise, the delay will start counting down when it is fulfilled and the returned promise will be fulfilled with the fulfillment value of the `value` promise. If `value` is a rejected promise, the resulting promise will be rejected immediately.
21 |
22 | ```js
23 | Promise.delay(500).then(function() {
24 | console.log("500 ms passed");
25 | return "Hello world";
26 | }).delay(500).then(function(helloWorldString) {
27 | console.log(helloWorldString);
28 | console.log("another 500 ms passed") ;
29 | });
30 | ```
31 |
32 |
33 |
10 | ##Promise.try
11 |
12 | ```js
13 | Promise.try(function() fn) -> Promise
14 | ```
15 | ```js
16 | Promise.attempt(function() fn) -> Promise
17 | ```
18 |
19 |
20 | Start the chain of promises with `Promise.try`. Any synchronous exceptions will be turned into rejections on the returned promise.
21 |
22 | ```js
23 | function getUserById(id) {
24 | return Promise.try(function() {
25 | if (typeof id !== "number") {
26 | throw new Error("id must be a number");
27 | }
28 | return db.getUserById(id);
29 | });
30 | }
31 | ```
32 |
33 | Now if someone uses this function, they will catch all errors in their Promise `.catch` handlers instead of having to handle both synchronous and asynchronous exception flows.
34 |
35 | *For compatibility with earlier ECMAScript version, an alias `Promise.attempt` is provided for [`Promise.try`](.).*
36 |
11 | ##Promise.each
12 |
13 | ```js
14 | Promise.each(
15 | Iterable|Promise> input,
16 | function(any item, int index, int length) iterator
17 | ) -> Promise
18 | ```
19 |
20 | [api/promise.each](unfinished-article)
21 |
22 | Iterate over an array, or a promise of an array, which contains promises (or a mix of promises and values) with the given `iterator` function with the signature `(value, index, length)` where `value` is the resolved value of a respective promise in the input array. **Iteration happens serially**. If the iterator function returns a promise or a thenable, then the result of the promise is awaited before continuing with next iteration. If any promise in the input array is rejected, then the returned promise is rejected as well.
23 |
24 | Resolves to the original array unmodified. This method is meant to be used for side effects.
25 |
26 |
27 |
10 | ##Promise.noConflict
11 |
12 | ```js
13 | Promise.noConflict() -> Object
14 | ```
15 |
16 |
17 | This is relevant to browser environments with no module loader.
18 |
19 | Release control of the `Promise` namespace to whatever it was before this library was loaded. Returns a reference to the library namespace so you can attach it to something else.
20 |
21 | ```html
22 |
23 |
24 |
25 |
32 | ```
33 |
10 | ##Promise.onPossiblyUnhandledRejection
11 |
12 | ```js
13 | Promise.onPossiblyUnhandledRejection(function(any error, Promise promise) handler) -> undefined
14 | ```
15 |
16 |
17 | *Note: this hook is specific to the bluebird instance its called on, application developers should use [global rejection events](/docs/api/error-management-configuration.html#global-rejection-events)*
18 |
19 | Add `handler` as the handler to call when there is a possibly unhandled rejection. The default handler logs the error stack to stderr or `console.error` in browsers.
20 |
21 | ```js
22 | Promise.onPossiblyUnhandledRejection(function(e, promise) {
23 | throw e;
24 | });
25 | ```
26 |
27 | Passing no value or a non-function will have the effect of removing any kind of handling for possibly unhandled rejections.
28 |
10 | ##.timeout
11 |
12 | ```js
13 | .timeout(
14 | int ms,
15 | [String message="operation timed out"]
16 | ) -> Promise
17 | ```
18 | ```js
19 | .timeout(
20 | int ms,
21 | [Error error]
22 | ) -> Promise
23 | ```
24 |
25 |
26 | Returns a promise that will be fulfilled with this promise's fulfillment value or rejection reason. However, if this promise is not fulfilled or rejected within `ms` milliseconds, the returned promise is rejected with a [`TimeoutError`](.) or the `error` as the reason.
27 |
28 | When using the first signature, you may specify a custom error message with the `message` parameter.
29 |
30 |
31 | ```js
32 | var Promise = require("bluebird");
33 | var fs = Promise.promisifyAll(require('fs'));
34 | fs.readFileAsync("huge-file.txt").timeout(100).then(function(fileContents) {
35 |
36 | }).catch(Promise.TimeoutError, function(e) {
37 | console.log("could not read file within 100ms");
38 | });
39 | ```
40 |
10 | ##Promise.race
11 |
12 | ```js
13 | Promise.race(Iterable|Promise> input) -> Promise
14 | ```
15 |
16 | Given an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)\(arrays are `Iterable`\), or a promise of an `Iterable`, which produces promises (or a mix of promises and values), iterate over all the values in the `Iterable` into an array and return a promise that is fulfilled or rejected as soon as a promise in the array is fulfilled or rejected with the respective rejection reason or fulfillment value.
17 |
18 | This method is only implemented because it's in the ES6 standard. If you want to race promises to fulfillment the [`.any`](.) method is more appropriate as it doesn't qualify a rejected promise as the winner. It also has less surprises: `.race` must become infinitely pending if an empty array is passed but passing an empty array to [`.any`](.) is more usefully a `RangeError`
19 |
10 | ##.tap
11 |
12 | ```js
13 | .tap(function(any value) handler) -> Promise
14 | ```
15 |
16 |
17 | Unlike [`.finally`](.) this is not called for rejections.
18 |
19 | ```js
20 | getUser().tap(function(user) {
21 | //Like in finally, if you return a promise from the handler
22 | //the promise is awaited for before passing the original value through
23 | return recordStatsAsync();
24 | }).then(function(user) {
25 | //user is the user from getUser(), not recordStatsAsync()
26 | });
27 | ```
28 |
29 | Common case includes adding logging to an existing promise chain:
30 |
31 | ```js
32 | doSomething()
33 | .then(...)
34 | .then(...)
35 | .then(...)
36 | .then(...)
37 | ```
38 |
39 | ```js
40 | doSomething()
41 | .then(...)
42 | .then(...)
43 | .tap(console.log)
44 | .then(...)
45 | .then(...)
46 | ```
47 |
48 | *Note: in browsers it is necessary to call `.tap` with `console.log.bind(console)` because console methods can not be called as stand-alone functions.*
49 |
10 | ##Promise.all
11 |
12 | ```js
13 | Promise.all(Iterable|Promise> input) -> Promise
14 | ```
15 |
16 | This method is useful for when you want to wait for more than one promise to complete.
17 |
18 | Given an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)\(arrays are `Iterable`\), or a promise of an `Iterable`, which produces promises (or a mix of promises and values), iterate over all the values in the `Iterable` into an array and return a promise that is fulfilled when all the items in the array are fulfilled. The promise's fulfillment value is an array with fulfillment values at respective positions to the original array. If any promise in the array rejects, the returned promise is rejected with the rejection reason.
19 |
20 |
21 | ```js
22 | var files = [];
23 | for (var i = 0; i < 100; ++i) {
24 | files.push(fs.writeFileAsync("file-" + i + ".txt", "", "utf-8"));
25 | }
26 | Promise.all(files).then(function() {
27 | console.log("all the files were created");
28 | });
29 | ```
30 |
31 |
32 | This method is compatible with [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) from native promises.
33 |
10 | ##Promise.onUnhandledRejectionHandled
11 |
12 | ```js
13 | Promise.onUnhandledRejectionHandled(function(Promise promise) handler) -> undefined
14 | ```
15 |
16 |
17 | *Note: this hook is specific to the bluebird instance its called on, application developers should use [global rejection events](/docs/api/error-management-configuration.html#global-rejection-events)*
18 |
19 | Add `handler` as the handler to call when a rejected promise that was reported as "possibly unhandled rejection" became handled.
20 |
21 | Together with `onPossiblyUnhandledRejection` these hooks can be used to implement a debugger that will show a list
22 | of unhandled promise rejections updated in real time as promises become handled.
23 |
24 | For example:
25 |
26 | ```js
27 | var unhandledPromises = [];
28 | Promise.onPossiblyUnhandledRejection(function(reason, promise) {
29 | unhandledPromises.push(promise);
30 | //Update some debugger UI
31 | });
32 |
33 | Promise.onUnhandledRejectionHandled(function(promise) {
34 | var index = unhandledPromises.indexOf(promise);
35 | unhandledPromises.splice(index, 1);
36 | //Update the debugger UI
37 | });
38 | ```
39 |
10 | ##Promise.setScheduler
11 |
12 | ```js
13 | Promise.setScheduler(function(function fn) scheduler) -> function
14 | ```
15 |
16 |
17 | Scheduler should be a function that asynchronously schedules the calling of the passed in function:
18 |
19 | ```js
20 | // This is just an example of how to use the api, there is no reason to do this
21 | Promise.setScheduler(function(fn) {
22 | setTimeout(fn, 0);
23 | });
24 | ```
25 |
26 | Setting a custom scheduler could be necessary when you need a faster way to schedule functions than bluebird does by default. It also makes bluebird possible to use in platforms where normal timing constructs like `setTimeout` and `process.nextTick` are not available (like Nashhorn).
27 |
28 | You can also use it as a hook:
29 |
30 | ```js
31 | // This will synchronize bluebird promise queue flushing with angulars queue flushing
32 | // Angular is also now responsible for choosing the actual scheduler
33 | Promise.setScheduler(function(fn) {
34 | $rootScope.$evalAsync(fn);
35 | });
36 | ```
37 |
38 | > **Danger** - in order to keep bluebird promises [Promises/A+](http://www.promisesaplus) compliant a scheduler that executes the function asynchronously (like the examples in this page) must be used.
39 |
40 |
10 | ##Promise.getNewLibraryCopy
11 |
12 | ```js
13 | Promise.getNewLibraryCopy() -> Object
14 | ```
15 |
16 | Returns a new independent copy of the Bluebird library.
17 |
18 | This method should be used before you use any of the methods which would otherwise alter the global `Bluebird` object - to avoid polluting global state.
19 |
20 | A basic example:
21 |
22 | ```js
23 | var Promise = require('bluebird');
24 | var Promise2 = Promise.getNewLibraryCopy();
25 |
26 | Promise2.x = 123;
27 |
28 | console.log(Promise2 == Promise); // false
29 | console.log(Promise2.x); // 123
30 | console.log(Promise.x); // undefined
31 | ```
32 |
33 | `Promise2` is independent to `Promise`. Any changes to `Promise2` do not affect the copy of Bluebird returned by `require('bluebird')`.
34 |
35 | In practice:
36 |
37 | ```js
38 | var Promise = require('bluebird').getNewLibraryCopy();
39 |
40 | Promise.coroutine.addYieldHandler( function() { /* */ } ); // alters behavior of `Promise.coroutine()`
41 |
42 | // somewhere in another file or module in same app
43 | var Promise = require('bluebird');
44 |
45 | Promise.coroutine(function*() {
46 | // this code is unaffected by the yieldHandler defined above
47 | // because it was defined on an independent copy of Bluebird
48 | });
49 | ```
50 |