1/*! 2 * @overview es6-promise - a tiny implementation of Promises/A+. 3 * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) 4 * @license Licensed under MIT license 5 * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE 6 * @version v4.2.8+1e68dce6 7 */ 8 9(function (global, factory) { 10 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 11 typeof define === 'function' && define.amd ? define(factory) : 12 (global.ES6Promise = factory()); 13}(this, (function () { 'use strict'; 14 15function objectOrFunction(x) { 16 var type = typeof x; 17 return x !== null && (type === 'object' || type === 'function'); 18} 19 20function isFunction(x) { 21 return typeof x === 'function'; 22} 23 24 25 26var _isArray = void 0; 27if (Array.isArray) { 28 _isArray = Array.isArray; 29} else { 30 _isArray = function (x) { 31 return Object.prototype.toString.call(x) === '[object Array]'; 32 }; 33} 34 35var isArray = _isArray; 36 37var len = 0; 38var vertxNext = void 0; 39var customSchedulerFn = void 0; 40 41var asap = function asap(callback, arg) { 42 queue[len] = callback; 43 queue[len + 1] = arg; 44 len += 2; 45 if (len === 2) { 46 // If len is 2, that means that we need to schedule an async flush. 47 // If additional callbacks are queued before the queue is flushed, they 48 // will be processed by this flush that we are scheduling. 49 if (customSchedulerFn) { 50 customSchedulerFn(flush); 51 } else { 52 scheduleFlush(); 53 } 54 } 55}; 56 57function setScheduler(scheduleFn) { 58 customSchedulerFn = scheduleFn; 59} 60 61function setAsap(asapFn) { 62 asap = asapFn; 63} 64 65var browserWindow = typeof window !== 'undefined' ? window : undefined; 66var browserGlobal = browserWindow || {}; 67var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; 68var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]'; 69 70// test for web worker but not in IE10 71var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined'; 72 73// node 74function useNextTick() { 75 // node version 0.10.x displays a deprecation warning when nextTick is used recursively 76 // see https://github.com/cujojs/when/issues/410 for details 77 return function () { 78 return process.nextTick(flush); 79 }; 80} 81 82// vertx 83function useVertxTimer() { 84 if (typeof vertxNext !== 'undefined') { 85 return function () { 86 vertxNext(flush); 87 }; 88 } 89 90 return useSetTimeout(); 91} 92 93function useMutationObserver() { 94 var iterations = 0; 95 var observer = new BrowserMutationObserver(flush); 96 var node = document.createTextNode(''); 97 observer.observe(node, { characterData: true }); 98 99 return function () { 100 node.data = iterations = ++iterations % 2; 101 }; 102} 103 104// web worker 105function useMessageChannel() { 106 var channel = new MessageChannel(); 107 channel.port1.onmessage = flush; 108 return function () { 109 return channel.port2.postMessage(0); 110 }; 111} 112 113function useSetTimeout() { 114 // Store setTimeout reference so es6-promise will be unaffected by 115 // other code modifying setTimeout (like sinon.useFakeTimers()) 116 var globalSetTimeout = setTimeout; 117 return function () { 118 return globalSetTimeout(flush, 1); 119 }; 120} 121 122var queue = new Array(1000); 123function flush() { 124 for (var i = 0; i < len; i += 2) { 125 var callback = queue[i]; 126 var arg = queue[i + 1]; 127 128 callback(arg); 129 130 queue[i] = undefined; 131 queue[i + 1] = undefined; 132 } 133 134 len = 0; 135} 136 137function attemptVertx() { 138 try { 139 var vertx = Function('return this')().require('vertx'); 140 vertxNext = vertx.runOnLoop || vertx.runOnContext; 141 return useVertxTimer(); 142 } catch (e) { 143 return useSetTimeout(); 144 } 145} 146 147var scheduleFlush = void 0; 148// Decide what async method to use to triggering processing of queued callbacks: 149if (isNode) { 150 scheduleFlush = useNextTick(); 151} else if (BrowserMutationObserver) { 152 scheduleFlush = useMutationObserver(); 153} else if (isWorker) { 154 scheduleFlush = useMessageChannel(); 155} else if (browserWindow === undefined && typeof require === 'function') { 156 scheduleFlush = attemptVertx(); 157} else { 158 scheduleFlush = useSetTimeout(); 159} 160 161function then(onFulfillment, onRejection) { 162 var parent = this; 163 164 var child = new this.constructor(noop); 165 166 if (child[PROMISE_ID] === undefined) { 167 makePromise(child); 168 } 169 170 var _state = parent._state; 171 172 173 if (_state) { 174 var callback = arguments[_state - 1]; 175 asap(function () { 176 return invokeCallback(_state, child, callback, parent._result); 177 }); 178 } else { 179 subscribe(parent, child, onFulfillment, onRejection); 180 } 181 182 return child; 183} 184 185/** 186 `Promise.resolve` returns a promise that will become resolved with the 187 passed `value`. It is shorthand for the following: 188 189 ```javascript 190 let promise = new Promise(function(resolve, reject){ 191 resolve(1); 192 }); 193 194 promise.then(function(value){ 195 // value === 1 196 }); 197 ``` 198 199 Instead of writing the above, your code now simply becomes the following: 200 201 ```javascript 202 let promise = Promise.resolve(1); 203 204 promise.then(function(value){ 205 // value === 1 206 }); 207 ``` 208 209 @method resolve 210 @static 211 @param {Any} value value that the returned promise will be resolved with 212 Useful for tooling. 213 @return {Promise} a promise that will become fulfilled with the given 214 `value` 215*/ 216function resolve$1(object) { 217 /*jshint validthis:true */ 218 var Constructor = this; 219 220 if (object && typeof object === 'object' && object.constructor === Constructor) { 221 return object; 222 } 223 224 var promise = new Constructor(noop); 225 resolve(promise, object); 226 return promise; 227} 228 229var PROMISE_ID = Math.random().toString(36).substring(2); 230 231function noop() {} 232 233var PENDING = void 0; 234var FULFILLED = 1; 235var REJECTED = 2; 236 237function selfFulfillment() { 238 return new TypeError("You cannot resolve a promise with itself"); 239} 240 241function cannotReturnOwn() { 242 return new TypeError('A promises callback cannot return that same promise.'); 243} 244 245function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) { 246 try { 247 then$$1.call(value, fulfillmentHandler, rejectionHandler); 248 } catch (e) { 249 return e; 250 } 251} 252 253function handleForeignThenable(promise, thenable, then$$1) { 254 asap(function (promise) { 255 var sealed = false; 256 var error = tryThen(then$$1, thenable, function (value) { 257 if (sealed) { 258 return; 259 } 260 sealed = true; 261 if (thenable !== value) { 262 resolve(promise, value); 263 } else { 264 fulfill(promise, value); 265 } 266 }, function (reason) { 267 if (sealed) { 268 return; 269 } 270 sealed = true; 271 272 reject(promise, reason); 273 }, 'Settle: ' + (promise._label || ' unknown promise')); 274 275 if (!sealed && error) { 276 sealed = true; 277 reject(promise, error); 278 } 279 }, promise); 280} 281 282function handleOwnThenable(promise, thenable) { 283 if (thenable._state === FULFILLED) { 284 fulfill(promise, thenable._result); 285 } else if (thenable._state === REJECTED) { 286 reject(promise, thenable._result); 287 } else { 288 subscribe(thenable, undefined, function (value) { 289 return resolve(promise, value); 290 }, function (reason) { 291 return reject(promise, reason); 292 }); 293 } 294} 295 296function handleMaybeThenable(promise, maybeThenable, then$$1) { 297 if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) { 298 handleOwnThenable(promise, maybeThenable); 299 } else { 300 if (then$$1 === undefined) { 301 fulfill(promise, maybeThenable); 302 } else if (isFunction(then$$1)) { 303 handleForeignThenable(promise, maybeThenable, then$$1); 304 } else { 305 fulfill(promise, maybeThenable); 306 } 307 } 308} 309 310function resolve(promise, value) { 311 if (promise === value) { 312 reject(promise, selfFulfillment()); 313 } else if (objectOrFunction(value)) { 314 var then$$1 = void 0; 315 try { 316 then$$1 = value.then; 317 } catch (error) { 318 reject(promise, error); 319 return; 320 } 321 handleMaybeThenable(promise, value, then$$1); 322 } else { 323 fulfill(promise, value); 324 } 325} 326 327function publishRejection(promise) { 328 if (promise._onerror) { 329 promise._onerror(promise._result); 330 } 331 332 publish(promise); 333} 334 335function fulfill(promise, value) { 336 if (promise._state !== PENDING) { 337 return; 338 } 339 340 promise._result = value; 341 promise._state = FULFILLED; 342 343 if (promise._subscribers.length !== 0) { 344 asap(publish, promise); 345 } 346} 347 348function reject(promise, reason) { 349 if (promise._state !== PENDING) { 350 return; 351 } 352 promise._state = REJECTED; 353 promise._result = reason; 354 355 asap(publishRejection, promise); 356} 357 358function subscribe(parent, child, onFulfillment, onRejection) { 359 var _subscribers = parent._subscribers; 360 var length = _subscribers.length; 361 362 363 parent._onerror = null; 364 365 _subscribers[length] = child; 366 _subscribers[length + FULFILLED] = onFulfillment; 367 _subscribers[length + REJECTED] = onRejection; 368 369 if (length === 0 && parent._state) { 370 asap(publish, parent); 371 } 372} 373 374function publish(promise) { 375 var subscribers = promise._subscribers; 376 var settled = promise._state; 377 378 if (subscribers.length === 0) { 379 return; 380 } 381 382 var child = void 0, 383 callback = void 0, 384 detail = promise._result; 385 386 for (var i = 0; i < subscribers.length; i += 3) { 387 child = subscribers[i]; 388 callback = subscribers[i + settled]; 389 390 if (child) { 391 invokeCallback(settled, child, callback, detail); 392 } else { 393 callback(detail); 394 } 395 } 396 397 promise._subscribers.length = 0; 398} 399 400function invokeCallback(settled, promise, callback, detail) { 401 var hasCallback = isFunction(callback), 402 value = void 0, 403 error = void 0, 404 succeeded = true; 405 406 if (hasCallback) { 407 try { 408 value = callback(detail); 409 } catch (e) { 410 succeeded = false; 411 error = e; 412 } 413 414 if (promise === value) { 415 reject(promise, cannotReturnOwn()); 416 return; 417 } 418 } else { 419 value = detail; 420 } 421 422 if (promise._state !== PENDING) { 423 // noop 424 } else if (hasCallback && succeeded) { 425 resolve(promise, value); 426 } else if (succeeded === false) { 427 reject(promise, error); 428 } else if (settled === FULFILLED) { 429 fulfill(promise, value); 430 } else if (settled === REJECTED) { 431 reject(promise, value); 432 } 433} 434 435function initializePromise(promise, resolver) { 436 try { 437 resolver(function resolvePromise(value) { 438 resolve(promise, value); 439 }, function rejectPromise(reason) { 440 reject(promise, reason); 441 }); 442 } catch (e) { 443 reject(promise, e); 444 } 445} 446 447var id = 0; 448function nextId() { 449 return id++; 450} 451 452function makePromise(promise) { 453 promise[PROMISE_ID] = id++; 454 promise._state = undefined; 455 promise._result = undefined; 456 promise._subscribers = []; 457} 458 459function validationError() { 460 return new Error('Array Methods must be provided an Array'); 461} 462 463var Enumerator = function () { 464 function Enumerator(Constructor, input) { 465 this._instanceConstructor = Constructor; 466 this.promise = new Constructor(noop); 467 468 if (!this.promise[PROMISE_ID]) { 469 makePromise(this.promise); 470 } 471 472 if (isArray(input)) { 473 this.length = input.length; 474 this._remaining = input.length; 475 476 this._result = new Array(this.length); 477 478 if (this.length === 0) { 479 fulfill(this.promise, this._result); 480 } else { 481 this.length = this.length || 0; 482 this._enumerate(input); 483 if (this._remaining === 0) { 484 fulfill(this.promise, this._result); 485 } 486 } 487 } else { 488 reject(this.promise, validationError()); 489 } 490 } 491 492 Enumerator.prototype._enumerate = function _enumerate(input) { 493 for (var i = 0; this._state === PENDING && i < input.length; i++) { 494 this._eachEntry(input[i], i); 495 } 496 }; 497 498 Enumerator.prototype._eachEntry = function _eachEntry(entry, i) { 499 var c = this._instanceConstructor; 500 var resolve$$1 = c.resolve; 501 502 503 if (resolve$$1 === resolve$1) { 504 var _then = void 0; 505 var error = void 0; 506 var didError = false; 507 try { 508 _then = entry.then; 509 } catch (e) { 510 didError = true; 511 error = e; 512 } 513 514 if (_then === then && entry._state !== PENDING) { 515 this._settledAt(entry._state, i, entry._result); 516 } else if (typeof _then !== 'function') { 517 this._remaining--; 518 this._result[i] = entry; 519 } else if (c === Promise$2) { 520 var promise = new c(noop); 521 if (didError) { 522 reject(promise, error); 523 } else { 524 handleMaybeThenable(promise, entry, _then); 525 } 526 this._willSettleAt(promise, i); 527 } else { 528 this._willSettleAt(new c(function (resolve$$1) { 529 return resolve$$1(entry); 530 }), i); 531 } 532 } else { 533 this._willSettleAt(resolve$$1(entry), i); 534 } 535 }; 536 537 Enumerator.prototype._settledAt = function _settledAt(state, i, value) { 538 var promise = this.promise; 539 540 541 if (promise._state === PENDING) { 542 this._remaining--; 543 544 if (state === REJECTED) { 545 reject(promise, value); 546 } else { 547 this._result[i] = value; 548 } 549 } 550 551 if (this._remaining === 0) { 552 fulfill(promise, this._result); 553 } 554 }; 555 556 Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) { 557 var enumerator = this; 558 559 subscribe(promise, undefined, function (value) { 560 return enumerator._settledAt(FULFILLED, i, value); 561 }, function (reason) { 562 return enumerator._settledAt(REJECTED, i, reason); 563 }); 564 }; 565 566 return Enumerator; 567}(); 568 569/** 570 `Promise.all` accepts an array of promises, and returns a new promise which 571 is fulfilled with an array of fulfillment values for the passed promises, or 572 rejected with the reason of the first passed promise to be rejected. It casts all 573 elements of the passed iterable to promises as it runs this algorithm. 574 575 Example: 576 577 ```javascript 578 let promise1 = resolve(1); 579 let promise2 = resolve(2); 580 let promise3 = resolve(3); 581 let promises = [ promise1, promise2, promise3 ]; 582 583 Promise.all(promises).then(function(array){ 584 // The array here would be [ 1, 2, 3 ]; 585 }); 586 ``` 587 588 If any of the `promises` given to `all` are rejected, the first promise 589 that is rejected will be given as an argument to the returned promises's 590 rejection handler. For example: 591 592 Example: 593 594 ```javascript 595 let promise1 = resolve(1); 596 let promise2 = reject(new Error("2")); 597 let promise3 = reject(new Error("3")); 598 let promises = [ promise1, promise2, promise3 ]; 599 600 Promise.all(promises).then(function(array){ 601 // Code here never runs because there are rejected promises! 602 }, function(error) { 603 // error.message === "2" 604 }); 605 ``` 606 607 @method all 608 @static 609 @param {Array} entries array of promises 610 @param {String} label optional string for labeling the promise. 611 Useful for tooling. 612 @return {Promise} promise that is fulfilled when all `promises` have been 613 fulfilled, or rejected if any of them become rejected. 614 @static 615*/ 616function all(entries) { 617 return new Enumerator(this, entries).promise; 618} 619 620/** 621 `Promise.race` returns a new promise which is settled in the same way as the 622 first passed promise to settle. 623 624 Example: 625 626 ```javascript 627 let promise1 = new Promise(function(resolve, reject){ 628 setTimeout(function(){ 629 resolve('promise 1'); 630 }, 200); 631 }); 632 633 let promise2 = new Promise(function(resolve, reject){ 634 setTimeout(function(){ 635 resolve('promise 2'); 636 }, 100); 637 }); 638 639 Promise.race([promise1, promise2]).then(function(result){ 640 // result === 'promise 2' because it was resolved before promise1 641 // was resolved. 642 }); 643 ``` 644 645 `Promise.race` is deterministic in that only the state of the first 646 settled promise matters. For example, even if other promises given to the 647 `promises` array argument are resolved, but the first settled promise has 648 become rejected before the other promises became fulfilled, the returned 649 promise will become rejected: 650 651 ```javascript 652 let promise1 = new Promise(function(resolve, reject){ 653 setTimeout(function(){ 654 resolve('promise 1'); 655 }, 200); 656 }); 657 658 let promise2 = new Promise(function(resolve, reject){ 659 setTimeout(function(){ 660 reject(new Error('promise 2')); 661 }, 100); 662 }); 663 664 Promise.race([promise1, promise2]).then(function(result){ 665 // Code here never runs 666 }, function(reason){ 667 // reason.message === 'promise 2' because promise 2 became rejected before 668 // promise 1 became fulfilled 669 }); 670 ``` 671 672 An example real-world use case is implementing timeouts: 673 674 ```javascript 675 Promise.race([ajax('foo.json'), timeout(5000)]) 676 ``` 677 678 @method race 679 @static 680 @param {Array} promises array of promises to observe 681 Useful for tooling. 682 @return {Promise} a promise which settles in the same way as the first passed 683 promise to settle. 684*/ 685function race(entries) { 686 /*jshint validthis:true */ 687 var Constructor = this; 688 689 if (!isArray(entries)) { 690 return new Constructor(function (_, reject) { 691 return reject(new TypeError('You must pass an array to race.')); 692 }); 693 } else { 694 return new Constructor(function (resolve, reject) { 695 var length = entries.length; 696 for (var i = 0; i < length; i++) { 697 Constructor.resolve(entries[i]).then(resolve, reject); 698 } 699 }); 700 } 701} 702 703/** 704 `Promise.reject` returns a promise rejected with the passed `reason`. 705 It is shorthand for the following: 706 707 ```javascript 708 let promise = new Promise(function(resolve, reject){ 709 reject(new Error('WHOOPS')); 710 }); 711 712 promise.then(function(value){ 713 // Code here doesn't run because the promise is rejected! 714 }, function(reason){ 715 // reason.message === 'WHOOPS' 716 }); 717 ``` 718 719 Instead of writing the above, your code now simply becomes the following: 720 721 ```javascript 722 let promise = Promise.reject(new Error('WHOOPS')); 723 724 promise.then(function(value){ 725 // Code here doesn't run because the promise is rejected! 726 }, function(reason){ 727 // reason.message === 'WHOOPS' 728 }); 729 ``` 730 731 @method reject 732 @static 733 @param {Any} reason value that the returned promise will be rejected with. 734 Useful for tooling. 735 @return {Promise} a promise rejected with the given `reason`. 736*/ 737function reject$1(reason) { 738 /*jshint validthis:true */ 739 var Constructor = this; 740 var promise = new Constructor(noop); 741 reject(promise, reason); 742 return promise; 743} 744 745function needsResolver() { 746 throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); 747} 748 749function needsNew() { 750 throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); 751} 752 753/** 754 Promise objects represent the eventual result of an asynchronous operation. The 755 primary way of interacting with a promise is through its `then` method, which 756 registers callbacks to receive either a promise's eventual value or the reason 757 why the promise cannot be fulfilled. 758 759 Terminology 760 ----------- 761 762 - `promise` is an object or function with a `then` method whose behavior conforms to this specification. 763 - `thenable` is an object or function that defines a `then` method. 764 - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). 765 - `exception` is a value that is thrown using the throw statement. 766 - `reason` is a value that indicates why a promise was rejected. 767 - `settled` the final resting state of a promise, fulfilled or rejected. 768 769 A promise can be in one of three states: pending, fulfilled, or rejected. 770 771 Promises that are fulfilled have a fulfillment value and are in the fulfilled 772 state. Promises that are rejected have a rejection reason and are in the 773 rejected state. A fulfillment value is never a thenable. 774 775 Promises can also be said to *resolve* a value. If this value is also a 776 promise, then the original promise's settled state will match the value's 777 settled state. So a promise that *resolves* a promise that rejects will 778 itself reject, and a promise that *resolves* a promise that fulfills will 779 itself fulfill. 780 781 782 Basic Usage: 783 ------------ 784 785 ```js 786 let promise = new Promise(function(resolve, reject) { 787 // on success 788 resolve(value); 789 790 // on failure 791 reject(reason); 792 }); 793 794 promise.then(function(value) { 795 // on fulfillment 796 }, function(reason) { 797 // on rejection 798 }); 799 ``` 800 801 Advanced Usage: 802 --------------- 803 804 Promises shine when abstracting away asynchronous interactions such as 805 `XMLHttpRequest`s. 806 807 ```js 808 function getJSON(url) { 809 return new Promise(function(resolve, reject){ 810 let xhr = new XMLHttpRequest(); 811 812 xhr.open('GET', url); 813 xhr.onreadystatechange = handler; 814 xhr.responseType = 'json'; 815 xhr.setRequestHeader('Accept', 'application/json'); 816 xhr.send(); 817 818 function handler() { 819 if (this.readyState === this.DONE) { 820 if (this.status === 200) { 821 resolve(this.response); 822 } else { 823 reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); 824 } 825 } 826 }; 827 }); 828 } 829 830 getJSON('/posts.json').then(function(json) { 831 // on fulfillment 832 }, function(reason) { 833 // on rejection 834 }); 835 ``` 836 837 Unlike callbacks, promises are great composable primitives. 838 839 ```js 840 Promise.all([ 841 getJSON('/posts'), 842 getJSON('/comments') 843 ]).then(function(values){ 844 values[0] // => postsJSON 845 values[1] // => commentsJSON 846 847 return values; 848 }); 849 ``` 850 851 @class Promise 852 @param {Function} resolver 853 Useful for tooling. 854 @constructor 855*/ 856 857var Promise$2 = function () { 858 function Promise(resolver) { 859 this[PROMISE_ID] = nextId(); 860 this._result = this._state = undefined; 861 this._subscribers = []; 862 863 if (noop !== resolver) { 864 typeof resolver !== 'function' && needsResolver(); 865 this instanceof Promise ? initializePromise(this, resolver) : needsNew(); 866 } 867 } 868 869 /** 870 The primary way of interacting with a promise is through its `then` method, 871 which registers callbacks to receive either a promise's eventual value or the 872 reason why the promise cannot be fulfilled. 873 ```js 874 findUser().then(function(user){ 875 // user is available 876 }, function(reason){ 877 // user is unavailable, and you are given the reason why 878 }); 879 ``` 880 Chaining 881 -------- 882 The return value of `then` is itself a promise. This second, 'downstream' 883 promise is resolved with the return value of the first promise's fulfillment 884 or rejection handler, or rejected if the handler throws an exception. 885 ```js 886 findUser().then(function (user) { 887 return user.name; 888 }, function (reason) { 889 return 'default name'; 890 }).then(function (userName) { 891 // If `findUser` fulfilled, `userName` will be the user's name, otherwise it 892 // will be `'default name'` 893 }); 894 findUser().then(function (user) { 895 throw new Error('Found user, but still unhappy'); 896 }, function (reason) { 897 throw new Error('`findUser` rejected and we're unhappy'); 898 }).then(function (value) { 899 // never reached 900 }, function (reason) { 901 // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. 902 // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. 903 }); 904 ``` 905 If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. 906 ```js 907 findUser().then(function (user) { 908 throw new PedagogicalException('Upstream error'); 909 }).then(function (value) { 910 // never reached 911 }).then(function (value) { 912 // never reached 913 }, function (reason) { 914 // The `PedgagocialException` is propagated all the way down to here 915 }); 916 ``` 917 Assimilation 918 ------------ 919 Sometimes the value you want to propagate to a downstream promise can only be 920 retrieved asynchronously. This can be achieved by returning a promise in the 921 fulfillment or rejection handler. The downstream promise will then be pending 922 until the returned promise is settled. This is called *assimilation*. 923 ```js 924 findUser().then(function (user) { 925 return findCommentsByAuthor(user); 926 }).then(function (comments) { 927 // The user's comments are now available 928 }); 929 ``` 930 If the assimliated promise rejects, then the downstream promise will also reject. 931 ```js 932 findUser().then(function (user) { 933 return findCommentsByAuthor(user); 934 }).then(function (comments) { 935 // If `findCommentsByAuthor` fulfills, we'll have the value here 936 }, function (reason) { 937 // If `findCommentsByAuthor` rejects, we'll have the reason here 938 }); 939 ``` 940 Simple Example 941 -------------- 942 Synchronous Example 943 ```javascript 944 let result; 945 try { 946 result = findResult(); 947 // success 948 } catch(reason) { 949 // failure 950 } 951 ``` 952 Errback Example 953 ```js 954 findResult(function(result, err){ 955 if (err) { 956 // failure 957 } else { 958 // success 959 } 960 }); 961 ``` 962 Promise Example; 963 ```javascript 964 findResult().then(function(result){ 965 // success 966 }, function(reason){ 967 // failure 968 }); 969 ``` 970 Advanced Example 971 -------------- 972 Synchronous Example 973 ```javascript 974 let author, books; 975 try { 976 author = findAuthor(); 977 books = findBooksByAuthor(author); 978 // success 979 } catch(reason) { 980 // failure 981 } 982 ``` 983 Errback Example 984 ```js 985 function foundBooks(books) { 986 } 987 function failure(reason) { 988 } 989 findAuthor(function(author, err){ 990 if (err) { 991 failure(err); 992 // failure 993 } else { 994 try { 995 findBoooksByAuthor(author, function(books, err) { 996 if (err) { 997 failure(err); 998 } else { 999 try { 1000 foundBooks(books); 1001 } catch(reason) { 1002 failure(reason); 1003 } 1004 } 1005 }); 1006 } catch(error) { 1007 failure(err); 1008 } 1009 // success 1010 } 1011 }); 1012 ``` 1013 Promise Example; 1014 ```javascript 1015 findAuthor(). 1016 then(findBooksByAuthor). 1017 then(function(books){ 1018 // found books 1019 }).catch(function(reason){ 1020 // something went wrong 1021 }); 1022 ``` 1023 @method then 1024 @param {Function} onFulfilled 1025 @param {Function} onRejected 1026 Useful for tooling. 1027 @return {Promise} 1028 */ 1029 1030 /** 1031 `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same 1032 as the catch block of a try/catch statement. 1033 ```js 1034 function findAuthor(){ 1035 throw new Error('couldn't find that author'); 1036 } 1037 // synchronous 1038 try { 1039 findAuthor(); 1040 } catch(reason) { 1041 // something went wrong 1042 } 1043 // async with promises 1044 findAuthor().catch(function(reason){ 1045 // something went wrong 1046 }); 1047 ``` 1048 @method catch 1049 @param {Function} onRejection 1050 Useful for tooling. 1051 @return {Promise} 1052 */ 1053 1054 1055 Promise.prototype.catch = function _catch(onRejection) { 1056 return this.then(null, onRejection); 1057 }; 1058 1059 /** 1060 `finally` will be invoked regardless of the promise's fate just as native 1061 try/catch/finally behaves 1062 1063 Synchronous example: 1064 1065 ```js 1066 findAuthor() { 1067 if (Math.random() > 0.5) { 1068 throw new Error(); 1069 } 1070 return new Author(); 1071 } 1072 1073 try { 1074 return findAuthor(); // succeed or fail 1075 } catch(error) { 1076 return findOtherAuther(); 1077 } finally { 1078 // always runs 1079 // doesn't affect the return value 1080 } 1081 ``` 1082 1083 Asynchronous example: 1084 1085 ```js 1086 findAuthor().catch(function(reason){ 1087 return findOtherAuther(); 1088 }).finally(function(){ 1089 // author was either found, or not 1090 }); 1091 ``` 1092 1093 @method finally 1094 @param {Function} callback 1095 @return {Promise} 1096 */ 1097 1098 1099 Promise.prototype.finally = function _finally(callback) { 1100 var promise = this; 1101 var constructor = promise.constructor; 1102 1103 if (isFunction(callback)) { 1104 return promise.then(function (value) { 1105 return constructor.resolve(callback()).then(function () { 1106 return value; 1107 }); 1108 }, function (reason) { 1109 return constructor.resolve(callback()).then(function () { 1110 throw reason; 1111 }); 1112 }); 1113 } 1114 1115 return promise.then(callback, callback); 1116 }; 1117 1118 return Promise; 1119}(); 1120 1121Promise$2.prototype.then = then; 1122Promise$2.all = all; 1123Promise$2.race = race; 1124Promise$2.resolve = resolve$1; 1125Promise$2.reject = reject$1; 1126Promise$2._setScheduler = setScheduler; 1127Promise$2._setAsap = setAsap; 1128Promise$2._asap = asap; 1129 1130/*global self*/ 1131function polyfill() { 1132 var local = void 0; 1133 1134 if (typeof global !== 'undefined') { 1135 local = global; 1136 } else if (typeof self !== 'undefined') { 1137 local = self; 1138 } else { 1139 try { 1140 local = Function('return this')(); 1141 } catch (e) { 1142 throw new Error('polyfill failed because global object is unavailable in this environment'); 1143 } 1144 } 1145 1146 var P = local.Promise; 1147 1148 if (P) { 1149 var promiseToString = null; 1150 try { 1151 promiseToString = Object.prototype.toString.call(P.resolve()); 1152 } catch (e) { 1153 // silently ignored 1154 } 1155 1156 if (promiseToString === '[object Promise]' && !P.cast) { 1157 return; 1158 } 1159 } 1160 1161 local.Promise = Promise$2; 1162} 1163 1164// Strange compat.. 1165Promise$2.polyfill = polyfill; 1166Promise$2.Promise = Promise$2; 1167 1168Promise$2.polyfill(); 1169 1170return Promise$2; 1171 1172}))); 1173 1174 1175 1176//# sourceMappingURL=es6-promise.auto.map 1177