UNPKG

23.3 kBJavaScriptView Raw
1/** @license MIT License (c) copyright 2010-2014 original author or authors */
2/** @author Brian Cavalier */
3/** @author John Hann */
4
5(function(define) { 'use strict';
6define(function() {
7
8 return function makePromise(environment) {
9
10 var tasks = environment.scheduler;
11 var emitRejection = initEmitRejection();
12
13 var objectCreate = Object.create ||
14 function(proto) {
15 function Child() {}
16 Child.prototype = proto;
17 return new Child();
18 };
19
20 /**
21 * Create a promise whose fate is determined by resolver
22 * @constructor
23 * @returns {Promise} promise
24 * @name Promise
25 */
26 function Promise(resolver, handler) {
27 this._handler = resolver === Handler ? handler : init(resolver);
28 }
29
30 /**
31 * Run the supplied resolver
32 * @param resolver
33 * @returns {Pending}
34 */
35 function init(resolver) {
36 var handler = new Pending();
37
38 try {
39 resolver(promiseResolve, promiseReject, promiseNotify);
40 } catch (e) {
41 promiseReject(e);
42 }
43
44 return handler;
45
46 /**
47 * Transition from pre-resolution state to post-resolution state, notifying
48 * all listeners of the ultimate fulfillment or rejection
49 * @param {*} x resolution value
50 */
51 function promiseResolve (x) {
52 handler.resolve(x);
53 }
54 /**
55 * Reject this promise with reason, which will be used verbatim
56 * @param {Error|*} reason rejection reason, strongly suggested
57 * to be an Error type
58 */
59 function promiseReject (reason) {
60 handler.reject(reason);
61 }
62
63 /**
64 * @deprecated
65 * Issue a progress event, notifying all progress listeners
66 * @param {*} x progress event payload to pass to all listeners
67 */
68 function promiseNotify (x) {
69 handler.notify(x);
70 }
71 }
72
73 // Creation
74
75 Promise.resolve = resolve;
76 Promise.reject = reject;
77 Promise.never = never;
78
79 Promise._defer = defer;
80 Promise._handler = getHandler;
81
82 /**
83 * Returns a trusted promise. If x is already a trusted promise, it is
84 * returned, otherwise returns a new trusted Promise which follows x.
85 * @param {*} x
86 * @return {Promise} promise
87 */
88 function resolve(x) {
89 return isPromise(x) ? x
90 : new Promise(Handler, new Async(getHandler(x)));
91 }
92
93 /**
94 * Return a reject promise with x as its reason (x is used verbatim)
95 * @param {*} x
96 * @returns {Promise} rejected promise
97 */
98 function reject(x) {
99 return new Promise(Handler, new Async(new Rejected(x)));
100 }
101
102 /**
103 * Return a promise that remains pending forever
104 * @returns {Promise} forever-pending promise.
105 */
106 function never() {
107 return foreverPendingPromise; // Should be frozen
108 }
109
110 /**
111 * Creates an internal {promise, resolver} pair
112 * @private
113 * @returns {Promise}
114 */
115 function defer() {
116 return new Promise(Handler, new Pending());
117 }
118
119 // Transformation and flow control
120
121 /**
122 * Transform this promise's fulfillment value, returning a new Promise
123 * for the transformed result. If the promise cannot be fulfilled, onRejected
124 * is called with the reason. onProgress *may* be called with updates toward
125 * this promise's fulfillment.
126 * @param {function=} onFulfilled fulfillment handler
127 * @param {function=} onRejected rejection handler
128 * @param {function=} onProgress @deprecated progress handler
129 * @return {Promise} new promise
130 */
131 Promise.prototype.then = function(onFulfilled, onRejected, onProgress) {
132 var parent = this._handler;
133 var state = parent.join().state();
134
135 if ((typeof onFulfilled !== 'function' && state > 0) ||
136 (typeof onRejected !== 'function' && state < 0)) {
137 // Short circuit: value will not change, simply share handler
138 return new this.constructor(Handler, parent);
139 }
140
141 var p = this._beget();
142 var child = p._handler;
143
144 parent.chain(child, parent.receiver, onFulfilled, onRejected, onProgress);
145
146 return p;
147 };
148
149 /**
150 * If this promise cannot be fulfilled due to an error, call onRejected to
151 * handle the error. Shortcut for .then(undefined, onRejected)
152 * @param {function?} onRejected
153 * @return {Promise}
154 */
155 Promise.prototype['catch'] = function(onRejected) {
156 return this.then(void 0, onRejected);
157 };
158
159 /**
160 * Creates a new, pending promise of the same type as this promise
161 * @private
162 * @returns {Promise}
163 */
164 Promise.prototype._beget = function() {
165 return begetFrom(this._handler, this.constructor);
166 };
167
168 function begetFrom(parent, Promise) {
169 var child = new Pending(parent.receiver, parent.join().context);
170 return new Promise(Handler, child);
171 }
172
173 // Array combinators
174
175 Promise.all = all;
176 Promise.race = race;
177 Promise._traverse = traverse;
178
179 /**
180 * Return a promise that will fulfill when all promises in the
181 * input array have fulfilled, or will reject when one of the
182 * promises rejects.
183 * @param {array} promises array of promises
184 * @returns {Promise} promise for array of fulfillment values
185 */
186 function all(promises) {
187 return traverseWith(snd, null, promises);
188 }
189
190 /**
191 * Array<Promise<X>> -> Promise<Array<f(X)>>
192 * @private
193 * @param {function} f function to apply to each promise's value
194 * @param {Array} promises array of promises
195 * @returns {Promise} promise for transformed values
196 */
197 function traverse(f, promises) {
198 return traverseWith(tryCatch2, f, promises);
199 }
200
201 function traverseWith(tryMap, f, promises) {
202 var handler = typeof f === 'function' ? mapAt : settleAt;
203
204 var resolver = new Pending();
205 var pending = promises.length >>> 0;
206 var results = new Array(pending);
207
208 for (var i = 0, x; i < promises.length && !resolver.resolved; ++i) {
209 x = promises[i];
210
211 if (x === void 0 && !(i in promises)) {
212 --pending;
213 continue;
214 }
215
216 traverseAt(promises, handler, i, x, resolver);
217 }
218
219 if(pending === 0) {
220 resolver.become(new Fulfilled(results));
221 }
222
223 return new Promise(Handler, resolver);
224
225 function mapAt(i, x, resolver) {
226 if(!resolver.resolved) {
227 traverseAt(promises, settleAt, i, tryMap(f, x, i), resolver);
228 }
229 }
230
231 function settleAt(i, x, resolver) {
232 results[i] = x;
233 if(--pending === 0) {
234 resolver.become(new Fulfilled(results));
235 }
236 }
237 }
238
239 function traverseAt(promises, handler, i, x, resolver) {
240 if (maybeThenable(x)) {
241 var h = getHandlerMaybeThenable(x);
242 var s = h.state();
243
244 if (s === 0) {
245 h.fold(handler, i, void 0, resolver);
246 } else if (s > 0) {
247 handler(i, h.value, resolver);
248 } else {
249 resolver.become(h);
250 visitRemaining(promises, i+1, h);
251 }
252 } else {
253 handler(i, x, resolver);
254 }
255 }
256
257 Promise._visitRemaining = visitRemaining;
258 function visitRemaining(promises, start, handler) {
259 for(var i=start; i<promises.length; ++i) {
260 markAsHandled(getHandler(promises[i]), handler);
261 }
262 }
263
264 function markAsHandled(h, handler) {
265 if(h === handler) {
266 return;
267 }
268
269 var s = h.state();
270 if(s === 0) {
271 h.visit(h, void 0, h._unreport);
272 } else if(s < 0) {
273 h._unreport();
274 }
275 }
276
277 /**
278 * Fulfill-reject competitive race. Return a promise that will settle
279 * to the same state as the earliest input promise to settle.
280 *
281 * WARNING: The ES6 Promise spec requires that race()ing an empty array
282 * must return a promise that is pending forever. This implementation
283 * returns a singleton forever-pending promise, the same singleton that is
284 * returned by Promise.never(), thus can be checked with ===
285 *
286 * @param {array} promises array of promises to race
287 * @returns {Promise} if input is non-empty, a promise that will settle
288 * to the same outcome as the earliest input promise to settle. if empty
289 * is empty, returns a promise that will never settle.
290 */
291 function race(promises) {
292 if(typeof promises !== 'object' || promises === null) {
293 return reject(new TypeError('non-iterable passed to race()'));
294 }
295
296 // Sigh, race([]) is untestable unless we return *something*
297 // that is recognizable without calling .then() on it.
298 return promises.length === 0 ? never()
299 : promises.length === 1 ? resolve(promises[0])
300 : runRace(promises);
301 }
302
303 function runRace(promises) {
304 var resolver = new Pending();
305 var i, x, h;
306 for(i=0; i<promises.length; ++i) {
307 x = promises[i];
308 if (x === void 0 && !(i in promises)) {
309 continue;
310 }
311
312 h = getHandler(x);
313 if(h.state() !== 0) {
314 resolver.become(h);
315 visitRemaining(promises, i+1, h);
316 break;
317 } else {
318 h.visit(resolver, resolver.resolve, resolver.reject);
319 }
320 }
321 return new Promise(Handler, resolver);
322 }
323
324 // Promise internals
325 // Below this, everything is @private
326
327 /**
328 * Get an appropriate handler for x, without checking for cycles
329 * @param {*} x
330 * @returns {object} handler
331 */
332 function getHandler(x) {
333 if(isPromise(x)) {
334 return x._handler.join();
335 }
336 return maybeThenable(x) ? getHandlerUntrusted(x) : new Fulfilled(x);
337 }
338
339 /**
340 * Get a handler for thenable x.
341 * NOTE: You must only call this if maybeThenable(x) == true
342 * @param {object|function|Promise} x
343 * @returns {object} handler
344 */
345 function getHandlerMaybeThenable(x) {
346 return isPromise(x) ? x._handler.join() : getHandlerUntrusted(x);
347 }
348
349 /**
350 * Get a handler for potentially untrusted thenable x
351 * @param {*} x
352 * @returns {object} handler
353 */
354 function getHandlerUntrusted(x) {
355 try {
356 var untrustedThen = x.then;
357 return typeof untrustedThen === 'function'
358 ? new Thenable(untrustedThen, x)
359 : new Fulfilled(x);
360 } catch(e) {
361 return new Rejected(e);
362 }
363 }
364
365 /**
366 * Handler for a promise that is pending forever
367 * @constructor
368 */
369 function Handler() {}
370
371 Handler.prototype.when
372 = Handler.prototype.become
373 = Handler.prototype.notify // deprecated
374 = Handler.prototype.fail
375 = Handler.prototype._unreport
376 = Handler.prototype._report
377 = noop;
378
379 Handler.prototype._state = 0;
380
381 Handler.prototype.state = function() {
382 return this._state;
383 };
384
385 /**
386 * Recursively collapse handler chain to find the handler
387 * nearest to the fully resolved value.
388 * @returns {object} handler nearest the fully resolved value
389 */
390 Handler.prototype.join = function() {
391 var h = this;
392 while(h.handler !== void 0) {
393 h = h.handler;
394 }
395 return h;
396 };
397
398 Handler.prototype.chain = function(to, receiver, fulfilled, rejected, progress) {
399 this.when({
400 resolver: to,
401 receiver: receiver,
402 fulfilled: fulfilled,
403 rejected: rejected,
404 progress: progress
405 });
406 };
407
408 Handler.prototype.visit = function(receiver, fulfilled, rejected, progress) {
409 this.chain(failIfRejected, receiver, fulfilled, rejected, progress);
410 };
411
412 Handler.prototype.fold = function(f, z, c, to) {
413 this.when(new Fold(f, z, c, to));
414 };
415
416 /**
417 * Handler that invokes fail() on any handler it becomes
418 * @constructor
419 */
420 function FailIfRejected() {}
421
422 inherit(Handler, FailIfRejected);
423
424 FailIfRejected.prototype.become = function(h) {
425 h.fail();
426 };
427
428 var failIfRejected = new FailIfRejected();
429
430 /**
431 * Handler that manages a queue of consumers waiting on a pending promise
432 * @constructor
433 */
434 function Pending(receiver, inheritedContext) {
435 Promise.createContext(this, inheritedContext);
436
437 this.consumers = void 0;
438 this.receiver = receiver;
439 this.handler = void 0;
440 this.resolved = false;
441 }
442
443 inherit(Handler, Pending);
444
445 Pending.prototype._state = 0;
446
447 Pending.prototype.resolve = function(x) {
448 this.become(getHandler(x));
449 };
450
451 Pending.prototype.reject = function(x) {
452 if(this.resolved) {
453 return;
454 }
455
456 this.become(new Rejected(x));
457 };
458
459 Pending.prototype.join = function() {
460 if (!this.resolved) {
461 return this;
462 }
463
464 var h = this;
465
466 while (h.handler !== void 0) {
467 h = h.handler;
468 if (h === this) {
469 return this.handler = cycle();
470 }
471 }
472
473 return h;
474 };
475
476 Pending.prototype.run = function() {
477 var q = this.consumers;
478 var handler = this.handler;
479 this.handler = this.handler.join();
480 this.consumers = void 0;
481
482 for (var i = 0; i < q.length; ++i) {
483 handler.when(q[i]);
484 }
485 };
486
487 Pending.prototype.become = function(handler) {
488 if(this.resolved) {
489 return;
490 }
491
492 this.resolved = true;
493 this.handler = handler;
494 if(this.consumers !== void 0) {
495 tasks.enqueue(this);
496 }
497
498 if(this.context !== void 0) {
499 handler._report(this.context);
500 }
501 };
502
503 Pending.prototype.when = function(continuation) {
504 if(this.resolved) {
505 tasks.enqueue(new ContinuationTask(continuation, this.handler));
506 } else {
507 if(this.consumers === void 0) {
508 this.consumers = [continuation];
509 } else {
510 this.consumers.push(continuation);
511 }
512 }
513 };
514
515 /**
516 * @deprecated
517 */
518 Pending.prototype.notify = function(x) {
519 if(!this.resolved) {
520 tasks.enqueue(new ProgressTask(x, this));
521 }
522 };
523
524 Pending.prototype.fail = function(context) {
525 var c = typeof context === 'undefined' ? this.context : context;
526 this.resolved && this.handler.join().fail(c);
527 };
528
529 Pending.prototype._report = function(context) {
530 this.resolved && this.handler.join()._report(context);
531 };
532
533 Pending.prototype._unreport = function() {
534 this.resolved && this.handler.join()._unreport();
535 };
536
537 /**
538 * Wrap another handler and force it into a future stack
539 * @param {object} handler
540 * @constructor
541 */
542 function Async(handler) {
543 this.handler = handler;
544 }
545
546 inherit(Handler, Async);
547
548 Async.prototype.when = function(continuation) {
549 tasks.enqueue(new ContinuationTask(continuation, this));
550 };
551
552 Async.prototype._report = function(context) {
553 this.join()._report(context);
554 };
555
556 Async.prototype._unreport = function() {
557 this.join()._unreport();
558 };
559
560 /**
561 * Handler that wraps an untrusted thenable and assimilates it in a future stack
562 * @param {function} then
563 * @param {{then: function}} thenable
564 * @constructor
565 */
566 function Thenable(then, thenable) {
567 Pending.call(this);
568 tasks.enqueue(new AssimilateTask(then, thenable, this));
569 }
570
571 inherit(Pending, Thenable);
572
573 /**
574 * Handler for a fulfilled promise
575 * @param {*} x fulfillment value
576 * @constructor
577 */
578 function Fulfilled(x) {
579 Promise.createContext(this);
580 this.value = x;
581 }
582
583 inherit(Handler, Fulfilled);
584
585 Fulfilled.prototype._state = 1;
586
587 Fulfilled.prototype.fold = function(f, z, c, to) {
588 runContinuation3(f, z, this, c, to);
589 };
590
591 Fulfilled.prototype.when = function(cont) {
592 runContinuation1(cont.fulfilled, this, cont.receiver, cont.resolver);
593 };
594
595 var errorId = 0;
596
597 /**
598 * Handler for a rejected promise
599 * @param {*} x rejection reason
600 * @constructor
601 */
602 function Rejected(x) {
603 Promise.createContext(this);
604
605 this.id = ++errorId;
606 this.value = x;
607 this.handled = false;
608 this.reported = false;
609
610 this._report();
611 }
612
613 inherit(Handler, Rejected);
614
615 Rejected.prototype._state = -1;
616
617 Rejected.prototype.fold = function(f, z, c, to) {
618 to.become(this);
619 };
620
621 Rejected.prototype.when = function(cont) {
622 if(typeof cont.rejected === 'function') {
623 this._unreport();
624 }
625 runContinuation1(cont.rejected, this, cont.receiver, cont.resolver);
626 };
627
628 Rejected.prototype._report = function(context) {
629 tasks.afterQueue(new ReportTask(this, context));
630 };
631
632 Rejected.prototype._unreport = function() {
633 if(this.handled) {
634 return;
635 }
636 this.handled = true;
637 tasks.afterQueue(new UnreportTask(this));
638 };
639
640 Rejected.prototype.fail = function(context) {
641 this.reported = true;
642 emitRejection('unhandledRejection', this);
643 Promise.onFatalRejection(this, context === void 0 ? this.context : context);
644 };
645
646 function ReportTask(rejection, context) {
647 this.rejection = rejection;
648 this.context = context;
649 }
650
651 ReportTask.prototype.run = function() {
652 if(!this.rejection.handled && !this.rejection.reported) {
653 this.rejection.reported = true;
654 emitRejection('unhandledRejection', this.rejection) ||
655 Promise.onPotentiallyUnhandledRejection(this.rejection, this.context);
656 }
657 };
658
659 function UnreportTask(rejection) {
660 this.rejection = rejection;
661 }
662
663 UnreportTask.prototype.run = function() {
664 if(this.rejection.reported) {
665 emitRejection('rejectionHandled', this.rejection) ||
666 Promise.onPotentiallyUnhandledRejectionHandled(this.rejection);
667 }
668 };
669
670 // Unhandled rejection hooks
671 // By default, everything is a noop
672
673 Promise.createContext
674 = Promise.enterContext
675 = Promise.exitContext
676 = Promise.onPotentiallyUnhandledRejection
677 = Promise.onPotentiallyUnhandledRejectionHandled
678 = Promise.onFatalRejection
679 = noop;
680
681 // Errors and singletons
682
683 var foreverPendingHandler = new Handler();
684 var foreverPendingPromise = new Promise(Handler, foreverPendingHandler);
685
686 function cycle() {
687 return new Rejected(new TypeError('Promise cycle'));
688 }
689
690 // Task runners
691
692 /**
693 * Run a single consumer
694 * @constructor
695 */
696 function ContinuationTask(continuation, handler) {
697 this.continuation = continuation;
698 this.handler = handler;
699 }
700
701 ContinuationTask.prototype.run = function() {
702 this.handler.join().when(this.continuation);
703 };
704
705 /**
706 * Run a queue of progress handlers
707 * @constructor
708 */
709 function ProgressTask(value, handler) {
710 this.handler = handler;
711 this.value = value;
712 }
713
714 ProgressTask.prototype.run = function() {
715 var q = this.handler.consumers;
716 if(q === void 0) {
717 return;
718 }
719
720 for (var c, i = 0; i < q.length; ++i) {
721 c = q[i];
722 runNotify(c.progress, this.value, this.handler, c.receiver, c.resolver);
723 }
724 };
725
726 /**
727 * Assimilate a thenable, sending it's value to resolver
728 * @param {function} then
729 * @param {object|function} thenable
730 * @param {object} resolver
731 * @constructor
732 */
733 function AssimilateTask(then, thenable, resolver) {
734 this._then = then;
735 this.thenable = thenable;
736 this.resolver = resolver;
737 }
738
739 AssimilateTask.prototype.run = function() {
740 var h = this.resolver;
741 tryAssimilate(this._then, this.thenable, _resolve, _reject, _notify);
742
743 function _resolve(x) { h.resolve(x); }
744 function _reject(x) { h.reject(x); }
745 function _notify(x) { h.notify(x); }
746 };
747
748 function tryAssimilate(then, thenable, resolve, reject, notify) {
749 try {
750 then.call(thenable, resolve, reject, notify);
751 } catch (e) {
752 reject(e);
753 }
754 }
755
756 /**
757 * Fold a handler value with z
758 * @constructor
759 */
760 function Fold(f, z, c, to) {
761 this.f = f; this.z = z; this.c = c; this.to = to;
762 this.resolver = failIfRejected;
763 this.receiver = this;
764 }
765
766 Fold.prototype.fulfilled = function(x) {
767 this.f.call(this.c, this.z, x, this.to);
768 };
769
770 Fold.prototype.rejected = function(x) {
771 this.to.reject(x);
772 };
773
774 Fold.prototype.progress = function(x) {
775 this.to.notify(x);
776 };
777
778 // Other helpers
779
780 /**
781 * @param {*} x
782 * @returns {boolean} true iff x is a trusted Promise
783 */
784 function isPromise(x) {
785 return x instanceof Promise;
786 }
787
788 /**
789 * Test just enough to rule out primitives, in order to take faster
790 * paths in some code
791 * @param {*} x
792 * @returns {boolean} false iff x is guaranteed *not* to be a thenable
793 */
794 function maybeThenable(x) {
795 return (typeof x === 'object' || typeof x === 'function') && x !== null;
796 }
797
798 function runContinuation1(f, h, receiver, next) {
799 if(typeof f !== 'function') {
800 return next.become(h);
801 }
802
803 Promise.enterContext(h);
804 tryCatchReject(f, h.value, receiver, next);
805 Promise.exitContext();
806 }
807
808 function runContinuation3(f, x, h, receiver, next) {
809 if(typeof f !== 'function') {
810 return next.become(h);
811 }
812
813 Promise.enterContext(h);
814 tryCatchReject3(f, x, h.value, receiver, next);
815 Promise.exitContext();
816 }
817
818 /**
819 * @deprecated
820 */
821 function runNotify(f, x, h, receiver, next) {
822 if(typeof f !== 'function') {
823 return next.notify(x);
824 }
825
826 Promise.enterContext(h);
827 tryCatchReturn(f, x, receiver, next);
828 Promise.exitContext();
829 }
830
831 function tryCatch2(f, a, b) {
832 try {
833 return f(a, b);
834 } catch(e) {
835 return reject(e);
836 }
837 }
838
839 /**
840 * Return f.call(thisArg, x), or if it throws return a rejected promise for
841 * the thrown exception
842 */
843 function tryCatchReject(f, x, thisArg, next) {
844 try {
845 next.become(getHandler(f.call(thisArg, x)));
846 } catch(e) {
847 next.become(new Rejected(e));
848 }
849 }
850
851 /**
852 * Same as above, but includes the extra argument parameter.
853 */
854 function tryCatchReject3(f, x, y, thisArg, next) {
855 try {
856 f.call(thisArg, x, y, next);
857 } catch(e) {
858 next.become(new Rejected(e));
859 }
860 }
861
862 /**
863 * @deprecated
864 * Return f.call(thisArg, x), or if it throws, *return* the exception
865 */
866 function tryCatchReturn(f, x, thisArg, next) {
867 try {
868 next.notify(f.call(thisArg, x));
869 } catch(e) {
870 next.notify(e);
871 }
872 }
873
874 function inherit(Parent, Child) {
875 Child.prototype = objectCreate(Parent.prototype);
876 Child.prototype.constructor = Child;
877 }
878
879 function snd(x, y) {
880 return y;
881 }
882
883 function noop() {}
884
885 function hasCustomEvent() {
886 if(typeof CustomEvent === 'function') {
887 try {
888 var ev = new CustomEvent('unhandledRejection');
889 return ev instanceof CustomEvent;
890 } catch (ignoredException) {}
891 }
892 return false;
893 }
894
895 function hasInternetExplorerCustomEvent() {
896 if(typeof document !== 'undefined' && typeof document.createEvent === 'function') {
897 try {
898 // Try to create one event to make sure it's supported
899 var ev = document.createEvent('CustomEvent');
900 ev.initCustomEvent('eventType', false, true, {});
901 return true;
902 } catch (ignoredException) {}
903 }
904 return false;
905 }
906
907 function initEmitRejection() {
908 /*global process, self, CustomEvent*/
909 if(typeof process !== 'undefined' && process !== null
910 && typeof process.emit === 'function') {
911 // Returning falsy here means to call the default
912 // onPotentiallyUnhandledRejection API. This is safe even in
913 // browserify since process.emit always returns falsy in browserify:
914 // https://github.com/defunctzombie/node-process/blob/master/browser.js#L40-L46
915 return function(type, rejection) {
916 return type === 'unhandledRejection'
917 ? process.emit(type, rejection.value, rejection)
918 : process.emit(type, rejection);
919 };
920 } else if(typeof self !== 'undefined' && hasCustomEvent()) {
921 return (function (self, CustomEvent) {
922 return function (type, rejection) {
923 var ev = new CustomEvent(type, {
924 detail: {
925 reason: rejection.value,
926 key: rejection
927 },
928 bubbles: false,
929 cancelable: true
930 });
931
932 return !self.dispatchEvent(ev);
933 };
934 }(self, CustomEvent));
935 } else if(typeof self !== 'undefined' && hasInternetExplorerCustomEvent()) {
936 return (function(self, document) {
937 return function(type, rejection) {
938 var ev = document.createEvent('CustomEvent');
939 ev.initCustomEvent(type, false, true, {
940 reason: rejection.value,
941 key: rejection
942 });
943
944 return !self.dispatchEvent(ev);
945 };
946 }(self, document));
947 }
948
949 return noop;
950 }
951
952 return Promise;
953 };
954});
955}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));