2 module.exports = function() {
3 var makeSelfResolutionError = function () {
4 return new TypeError("circular promise resolution chain\u000a\u000a See http://goo.gl/MqrFmX\u000a");
6 var reflectHandler = function() {
7 return new Promise.PromiseInspection(this._target());
9 var apiRejection = function(msg) {
10 return Promise.reject(new TypeError(msg));
12 function Proxyable() {}
13 var UNDEFINED_BINDING = {};
14 var util = require("./util");
18 getDomain = function() {
19 var ret = process.domain;
20 if (ret === undefined) ret = null;
24 getDomain = function() {
28 util.notEnumerableProp(Promise, "_getDomain", getDomain);
30 var es5 = require("./es5");
31 var Async = require("./async");
32 var async = new Async();
33 es5.defineProperty(Promise, "_async", {value: async});
34 var errors = require("./errors");
35 var TypeError = Promise.TypeError = errors.TypeError;
36 Promise.RangeError = errors.RangeError;
37 var CancellationError = Promise.CancellationError = errors.CancellationError;
38 Promise.TimeoutError = errors.TimeoutError;
39 Promise.OperationalError = errors.OperationalError;
40 Promise.RejectionError = errors.OperationalError;
41 Promise.AggregateError = errors.AggregateError;
42 var INTERNAL = function(){};
45 var tryConvertToPromise = require("./thenables")(Promise, INTERNAL);
47 require("./promise_array")(Promise, INTERNAL,
48 tryConvertToPromise, apiRejection, Proxyable);
49 var Context = require("./context")(Promise);
50 /*jshint unused:false*/
51 var createContext = Context.create;
52 var debug = require("./debuggability")(Promise, Context);
53 var CapturedTrace = debug.CapturedTrace;
54 var PassThroughHandlerContext =
55 require("./finally")(Promise, tryConvertToPromise);
56 var catchFilter = require("./catch_filter")(NEXT_FILTER);
57 var nodebackForPromise = require("./nodeback");
58 var errorObj = util.errorObj;
59 var tryCatch = util.tryCatch;
60 function check(self, executor) {
61 if (typeof executor !== "function") {
62 throw new TypeError("expecting a function but got " + util.classString(executor));
64 if (self.constructor !== Promise) {
65 throw new TypeError("the promise constructor cannot be invoked directly\u000a\u000a See http://goo.gl/MqrFmX\u000a");
69 function Promise(executor) {
71 this._fulfillmentHandler0 = undefined;
72 this._rejectionHandler0 = undefined;
73 this._promise0 = undefined;
74 this._receiver0 = undefined;
75 if (executor !== INTERNAL) {
76 check(this, executor);
77 this._resolveFromExecutor(executor);
79 this._promiseCreated();
82 Promise.prototype.toString = function () {
83 return "[object Promise]";
86 Promise.prototype.caught = Promise.prototype["catch"] = function (fn) {
87 var len = arguments.length;
89 var catchInstances = new Array(len - 1),
91 for (i = 0; i < len - 1; ++i) {
92 var item = arguments[i];
93 if (util.isObject(item)) {
94 catchInstances[j++] = item;
96 return apiRejection("expecting an object but got " + util.classString(item));
99 catchInstances.length = j;
101 return this.then(undefined, catchFilter(catchInstances, fn, this));
103 return this.then(undefined, fn);
106 Promise.prototype.reflect = function () {
107 return this._then(reflectHandler,
108 reflectHandler, undefined, this, undefined);
111 Promise.prototype.then = function (didFulfill, didReject) {
112 if (debug.warnings() && arguments.length > 0 &&
113 typeof didFulfill !== "function" &&
114 typeof didReject !== "function") {
115 var msg = ".then() only accepts functions but was passed: " +
116 util.classString(didFulfill);
117 if (arguments.length > 1) {
118 msg += ", " + util.classString(didReject);
122 return this._then(didFulfill, didReject, undefined, undefined, undefined);
125 Promise.prototype.done = function (didFulfill, didReject) {
127 this._then(didFulfill, didReject, undefined, undefined, undefined);
128 promise._setIsFinal();
131 Promise.prototype.spread = function (fn) {
132 if (typeof fn !== "function") {
133 return apiRejection("expecting a function but got " + util.classString(fn));
135 return this.all()._then(fn, undefined, undefined, APPLY, undefined);
138 Promise.prototype.toJSON = function () {
142 fulfillmentValue: undefined,
143 rejectionReason: undefined
145 if (this.isFulfilled()) {
146 ret.fulfillmentValue = this.value();
147 ret.isFulfilled = true;
148 } else if (this.isRejected()) {
149 ret.rejectionReason = this.reason();
150 ret.isRejected = true;
155 Promise.prototype.all = function () {
156 if (arguments.length > 0) {
157 this._warn(".all() was passed arguments but it does not take any");
159 return new PromiseArray(this).promise();
162 Promise.prototype.error = function (fn) {
163 return this.caught(util.originatesFromRejection, fn);
166 Promise.is = function (val) {
167 return val instanceof Promise;
170 Promise.fromNode = Promise.fromCallback = function(fn) {
171 var ret = new Promise(INTERNAL);
172 ret._captureStackTrace();
173 var multiArgs = arguments.length > 1 ? !!Object(arguments[1]).multiArgs
175 var result = tryCatch(fn)(nodebackForPromise(ret, multiArgs));
176 if (result === errorObj) {
177 ret._rejectCallback(result.e, true);
179 if (!ret._isFateSealed()) ret._setAsyncGuaranteed();
183 Promise.all = function (promises) {
184 return new PromiseArray(promises).promise();
187 Promise.cast = function (obj) {
188 var ret = tryConvertToPromise(obj);
189 if (!(ret instanceof Promise)) {
190 ret = new Promise(INTERNAL);
191 ret._captureStackTrace();
193 ret._rejectionHandler0 = obj;
198 Promise.resolve = Promise.fulfilled = Promise.cast;
200 Promise.reject = Promise.rejected = function (reason) {
201 var ret = new Promise(INTERNAL);
202 ret._captureStackTrace();
203 ret._rejectCallback(reason, true);
207 Promise.setScheduler = function(fn) {
208 if (typeof fn !== "function") {
209 throw new TypeError("expecting a function but got " + util.classString(fn));
211 var prev = async._schedule;
212 async._schedule = fn;
216 Promise.prototype._then = function (
222 var haveInternalData = internalData !== undefined;
223 var promise = haveInternalData ? internalData : new Promise(INTERNAL);
224 var target = this._target();
225 var bitField = target._bitField;
227 if (!haveInternalData) {
228 promise._propagateFrom(this, 3);
229 promise._captureStackTrace();
230 if (receiver === undefined &&
231 ((this._bitField & 2097152) !== 0)) {
232 if (!((bitField & 50397184) === 0)) {
233 receiver = this._boundValue();
235 receiver = target === this ? undefined : this._boundTo;
240 var domain = getDomain();
241 if (!((bitField & 50397184) === 0)) {
242 var handler, value, settler = target._settlePromiseCtx;
243 if (((bitField & 33554432) !== 0)) {
244 value = target._rejectionHandler0;
245 handler = didFulfill;
246 } else if (((bitField & 16777216) !== 0)) {
247 value = target._fulfillmentHandler0;
249 target._unsetRejectionIsUnhandled();
251 settler = target._settlePromiseLateCancellationObserver;
252 value = new CancellationError("late cancellation observer");
253 target._attachExtraTrace(value);
257 async.invoke(settler, target, {
258 handler: domain === null ? handler
259 : (typeof handler === "function" && domain.bind(handler)),
265 target._addCallbacks(didFulfill, didReject, promise, receiver, domain);
271 Promise.prototype._length = function () {
272 return this._bitField & 65535;
275 Promise.prototype._isFateSealed = function () {
276 return (this._bitField & 117506048) !== 0;
279 Promise.prototype._isFollowing = function () {
280 return (this._bitField & 67108864) === 67108864;
283 Promise.prototype._setLength = function (len) {
284 this._bitField = (this._bitField & -65536) |
288 Promise.prototype._setFulfilled = function () {
289 this._bitField = this._bitField | 33554432;
292 Promise.prototype._setRejected = function () {
293 this._bitField = this._bitField | 16777216;
296 Promise.prototype._setFollowing = function () {
297 this._bitField = this._bitField | 67108864;
300 Promise.prototype._setIsFinal = function () {
301 this._bitField = this._bitField | 4194304;
304 Promise.prototype._isFinal = function () {
305 return (this._bitField & 4194304) > 0;
308 Promise.prototype._unsetCancelled = function() {
309 this._bitField = this._bitField & (~65536);
312 Promise.prototype._setCancelled = function() {
313 this._bitField = this._bitField | 65536;
316 Promise.prototype._setAsyncGuaranteed = function() {
317 this._bitField = this._bitField | 134217728;
320 Promise.prototype._receiverAt = function (index) {
321 var ret = index === 0 ? this._receiver0 : this[
323 if (ret === UNDEFINED_BINDING) {
325 } else if (ret === undefined && this._isBound()) {
326 return this._boundValue();
331 Promise.prototype._promiseAt = function (index) {
336 Promise.prototype._fulfillmentHandlerAt = function (index) {
341 Promise.prototype._rejectionHandlerAt = function (index) {
346 Promise.prototype._boundValue = function() {};
348 Promise.prototype._migrateCallback0 = function (follower) {
349 var bitField = follower._bitField;
350 var fulfill = follower._fulfillmentHandler0;
351 var reject = follower._rejectionHandler0;
352 var promise = follower._promise0;
353 var receiver = follower._receiverAt(0);
354 if (receiver === undefined) receiver = UNDEFINED_BINDING;
355 this._addCallbacks(fulfill, reject, promise, receiver, null);
358 Promise.prototype._migrateCallbackAt = function (follower, index) {
359 var fulfill = follower._fulfillmentHandlerAt(index);
360 var reject = follower._rejectionHandlerAt(index);
361 var promise = follower._promiseAt(index);
362 var receiver = follower._receiverAt(index);
363 if (receiver === undefined) receiver = UNDEFINED_BINDING;
364 this._addCallbacks(fulfill, reject, promise, receiver, null);
367 Promise.prototype._addCallbacks = function (
374 var index = this._length();
376 if (index >= 65535 - 4) {
382 this._promise0 = promise;
383 this._receiver0 = receiver;
384 if (typeof fulfill === "function") {
385 this._fulfillmentHandler0 =
386 domain === null ? fulfill : domain.bind(fulfill);
388 if (typeof reject === "function") {
389 this._rejectionHandler0 =
390 domain === null ? reject : domain.bind(reject);
393 var base = index * 4 - 4;
394 this[base + 2] = promise;
395 this[base + 3] = receiver;
396 if (typeof fulfill === "function") {
398 domain === null ? fulfill : domain.bind(fulfill);
400 if (typeof reject === "function") {
402 domain === null ? reject : domain.bind(reject);
405 this._setLength(index + 1);
409 Promise.prototype._proxy = function (proxyable, arg) {
410 this._addCallbacks(undefined, undefined, arg, proxyable, null);
413 Promise.prototype._resolveCallback = function(value, shouldBind) {
414 if (((this._bitField & 117506048) !== 0)) return;
416 return this._rejectCallback(makeSelfResolutionError(), false);
417 var maybePromise = tryConvertToPromise(value, this);
418 if (!(maybePromise instanceof Promise)) return this._fulfill(value);
420 if (shouldBind) this._propagateFrom(maybePromise, 2);
422 var promise = maybePromise._target();
423 var bitField = promise._bitField;
424 if (((bitField & 50397184) === 0)) {
425 var len = this._length();
426 if (len > 0) promise._migrateCallback0(this);
427 for (var i = 1; i < len; ++i) {
428 promise._migrateCallbackAt(this, i);
430 this._setFollowing();
432 this._setFollowee(promise);
433 } else if (((bitField & 33554432) !== 0)) {
434 this._fulfill(promise._value());
435 } else if (((bitField & 16777216) !== 0)) {
436 this._reject(promise._reason());
438 var reason = new CancellationError("late cancellation observer");
439 promise._attachExtraTrace(reason);
440 this._reject(reason);
444 Promise.prototype._rejectCallback =
445 function(reason, synchronous, ignoreNonErrorWarnings) {
446 var trace = util.ensureErrorObject(reason);
447 var hasStack = trace === reason;
448 if (!hasStack && !ignoreNonErrorWarnings && debug.warnings()) {
449 var message = "a promise was rejected with a non-error: " +
450 util.classString(reason);
451 this._warn(message, true);
453 this._attachExtraTrace(trace, synchronous ? hasStack : false);
454 this._reject(reason);
457 Promise.prototype._resolveFromExecutor = function (executor) {
459 this._captureStackTrace();
461 var synchronous = true;
462 var r = this._execute(executor, function(value) {
463 promise._resolveCallback(value);
464 }, function (reason) {
465 promise._rejectCallback(reason, synchronous);
470 if (r !== undefined) {
471 promise._rejectCallback(r, true);
475 Promise.prototype._settlePromiseFromHandler = function (
476 handler, receiver, value, promise
478 var bitField = promise._bitField;
479 if (((bitField & 65536) !== 0)) return;
480 promise._pushContext();
482 if (receiver === APPLY) {
483 if (!value || typeof value.length !== "number") {
485 x.e = new TypeError("cannot .spread() a non-array: " +
486 util.classString(value));
488 x = tryCatch(handler).apply(this._boundValue(), value);
491 x = tryCatch(handler).call(receiver, value);
493 var promiseCreated = promise._popContext();
494 bitField = promise._bitField;
495 if (((bitField & 65536) !== 0)) return;
497 if (x === NEXT_FILTER) {
498 promise._reject(value);
499 } else if (x === errorObj || x === promise) {
500 var err = x === promise ? makeSelfResolutionError() : x.e;
501 promise._rejectCallback(err, false);
503 debug.checkForgottenReturns(x, promiseCreated, "", promise, this);
504 promise._resolveCallback(x);
508 Promise.prototype._target = function() {
510 while (ret._isFollowing()) ret = ret._followee();
514 Promise.prototype._followee = function() {
515 return this._rejectionHandler0;
518 Promise.prototype._setFollowee = function(promise) {
519 this._rejectionHandler0 = promise;
522 Promise.prototype._settlePromise = function(promise, handler, receiver, value) {
523 var isPromise = promise instanceof Promise;
524 var bitField = this._bitField;
525 var asyncGuaranteed = ((bitField & 134217728) !== 0);
526 if (((bitField & 65536) !== 0)) {
527 if (isPromise) promise._invokeInternalOnCancel();
529 if (receiver instanceof PassThroughHandlerContext) {
530 receiver.cancelPromise = promise;
531 if (tryCatch(handler).call(receiver, value) === errorObj) {
532 promise._reject(errorObj.e);
534 } else if (handler === reflectHandler) {
535 promise._fulfill(reflectHandler.call(receiver));
536 } else if (receiver instanceof Proxyable) {
537 receiver._promiseCancelled(promise);
538 } else if (isPromise || promise instanceof PromiseArray) {
543 } else if (typeof handler === "function") {
545 handler.call(receiver, value, promise);
547 if (asyncGuaranteed) promise._setAsyncGuaranteed();
548 this._settlePromiseFromHandler(handler, receiver, value, promise);
550 } else if (receiver instanceof Proxyable) {
551 if (!receiver._isResolved()) {
552 if (((bitField & 33554432) !== 0)) {
553 receiver._promiseFulfilled(value, promise);
555 receiver._promiseRejected(value, promise);
558 } else if (isPromise) {
559 if (asyncGuaranteed) promise._setAsyncGuaranteed();
560 if (((bitField & 33554432) !== 0)) {
561 promise._fulfill(value);
563 promise._reject(value);
568 Promise.prototype._settlePromiseLateCancellationObserver = function(ctx) {
569 var handler = ctx.handler;
570 var promise = ctx.promise;
571 var receiver = ctx.receiver;
572 var value = ctx.value;
573 if (typeof handler === "function") {
574 if (!(promise instanceof Promise)) {
575 handler.call(receiver, value, promise);
577 this._settlePromiseFromHandler(handler, receiver, value, promise);
579 } else if (promise instanceof Promise) {
580 promise._reject(value);
584 Promise.prototype._settlePromiseCtx = function(ctx) {
585 this._settlePromise(ctx.promise, ctx.handler, ctx.receiver, ctx.value);
588 Promise.prototype._settlePromise0 = function(handler, value, bitField) {
589 var promise = this._promise0;
590 var receiver = this._receiverAt(0);
591 this._promise0 = undefined;
592 this._receiver0 = undefined;
593 this._settlePromise(promise, handler, receiver, value);
596 Promise.prototype._clearCallbackDataAtIndex = function(index) {
597 var base = index * 4 - 4;
601 this[base + 1] = undefined;
604 Promise.prototype._fulfill = function (value) {
605 var bitField = this._bitField;
606 if (((bitField & 117506048) >>> 16)) return;
607 if (value === this) {
608 var err = makeSelfResolutionError();
609 this._attachExtraTrace(err);
610 return this._reject(err);
612 this._setFulfilled();
613 this._rejectionHandler0 = value;
615 if ((bitField & 65535) > 0) {
616 if (((bitField & 134217728) !== 0)) {
617 this._settlePromises();
619 async.settlePromises(this);
624 Promise.prototype._reject = function (reason) {
625 var bitField = this._bitField;
626 if (((bitField & 117506048) >>> 16)) return;
628 this._fulfillmentHandler0 = reason;
630 if (this._isFinal()) {
631 return async.fatalError(reason, util.isNode);
634 if ((bitField & 65535) > 0) {
635 if (((bitField & 134217728) !== 0)) {
636 this._settlePromises();
638 async.settlePromises(this);
641 this._ensurePossibleRejectionHandled();
645 Promise.prototype._fulfillPromises = function (len, value) {
646 for (var i = 1; i < len; i++) {
647 var handler = this._fulfillmentHandlerAt(i);
648 var promise = this._promiseAt(i);
649 var receiver = this._receiverAt(i);
650 this._clearCallbackDataAtIndex(i);
651 this._settlePromise(promise, handler, receiver, value);
655 Promise.prototype._rejectPromises = function (len, reason) {
656 for (var i = 1; i < len; i++) {
657 var handler = this._rejectionHandlerAt(i);
658 var promise = this._promiseAt(i);
659 var receiver = this._receiverAt(i);
660 this._clearCallbackDataAtIndex(i);
661 this._settlePromise(promise, handler, receiver, reason);
665 Promise.prototype._settlePromises = function () {
666 var bitField = this._bitField;
667 var len = (bitField & 65535);
670 if (((bitField & 16842752) !== 0)) {
671 var reason = this._fulfillmentHandler0;
672 this._settlePromise0(this._rejectionHandler0, reason, bitField);
673 this._rejectPromises(len, reason);
675 var value = this._rejectionHandler0;
676 this._settlePromise0(this._fulfillmentHandler0, value, bitField);
677 this._fulfillPromises(len, value);
681 this._clearCancellationData();
684 Promise.prototype._settledValue = function() {
685 var bitField = this._bitField;
686 if (((bitField & 33554432) !== 0)) {
687 return this._rejectionHandler0;
688 } else if (((bitField & 16777216) !== 0)) {
689 return this._fulfillmentHandler0;
693 function deferResolve(v) {this.promise._resolveCallback(v);}
694 function deferReject(v) {this.promise._rejectCallback(v, false);}
696 Promise.defer = Promise.pending = function() {
697 debug.deprecated("Promise.defer", "new Promise");
698 var promise = new Promise(INTERNAL);
701 resolve: deferResolve,
706 util.notEnumerableProp(Promise,
707 "_makeSelfResolutionError",
708 makeSelfResolutionError);
710 require("./method")(Promise, INTERNAL, tryConvertToPromise, apiRejection,
712 require("./bind")(Promise, INTERNAL, tryConvertToPromise, debug);
713 require("./cancel")(Promise, PromiseArray, apiRejection, debug);
714 require("./direct_resolve")(Promise);
715 require("./synchronous_inspection")(Promise);
717 Promise, PromiseArray, tryConvertToPromise, INTERNAL, debug);
718 Promise.Promise = Promise;
719 require('./map.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug);
720 require('./using.js')(Promise, apiRejection, tryConvertToPromise, createContext, INTERNAL, debug);
721 require('./timers.js')(Promise, INTERNAL, debug);
722 require('./generators.js')(Promise, apiRejection, INTERNAL, tryConvertToPromise, Proxyable, debug);
723 require('./nodeify.js')(Promise);
724 require('./call_get.js')(Promise);
725 require('./props.js')(Promise, PromiseArray, tryConvertToPromise, apiRejection);
726 require('./race.js')(Promise, INTERNAL, tryConvertToPromise, apiRejection);
727 require('./reduce.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug);
728 require('./settle.js')(Promise, PromiseArray, debug);
729 require('./some.js')(Promise, PromiseArray, apiRejection);
730 require('./promisify.js')(Promise, INTERNAL);
731 require('./any.js')(Promise);
732 require('./each.js')(Promise, INTERNAL);
733 require('./filter.js')(Promise, INTERNAL);
735 util.toFastProperties(Promise);
736 util.toFastProperties(Promise.prototype);
737 function fillTypes(value) {
738 var p = new Promise(INTERNAL);
739 p._fulfillmentHandler0 = value;
740 p._rejectionHandler0 = value;
742 p._receiver0 = value;
744 // Complete slack tracking, opt out of field-type tracking and
750 fillTypes(function(){});
751 fillTypes(undefined);
753 fillTypes(new Promise(INTERNAL));
754 debug.setBounds(Async.firstLineError, util.lastLineError);