makePromise.js 20 KB

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