1 | /**
|
2 | * This is the minimal implementation of Yaku.
|
3 | * No extra helper methods.
|
4 | */
|
5 |
|
6 | (function () {
|
7 | ;
|
8 |
|
9 | var $undefined
|
10 | , $null = null
|
11 | , isBrowser = typeof window === "object"
|
12 | , root = isBrowser ? window : global
|
13 | , process = root.process
|
14 | , Arr = Array
|
15 |
|
16 | , $rejected = 0
|
17 | , $resolved = 1
|
18 | , $pending = 2
|
19 |
|
20 | , $Symbol = "Symbol"
|
21 | , $iterator = "iterator"
|
22 | , $species = "species"
|
23 | , $speciesKey = $Symbol + "(" + $species + ")"
|
24 | , $return = "return"
|
25 |
|
26 | , $unhandled = "_uh"
|
27 |
|
28 | , $invalidThis = "Invalid this"
|
29 | , $invalidArgument = "Invalid argument"
|
30 | , $promiseCircularChain = "Chaining cycle detected for promise"
|
31 | , $rejectionHandled = "rejectionHandled"
|
32 | , $unhandledRejection = "unhandledRejection"
|
33 |
|
34 | , $tryCatchFn
|
35 | , $tryCatchThis
|
36 | , $tryErr = { e: $null }
|
37 | , $noop = function () {}
|
38 |
|
39 | , Symbol = root[$Symbol] || {}
|
40 | , nextTick = isBrowser ?
|
41 | function (fn) { setTimeout(fn); } :
|
42 | process.nextTick
|
43 | , speciesConstructor = function (O, D) {
|
44 | var C = O.constructor;
|
45 |
|
46 | return C ? (C[getSpecies()] || D) : D;
|
47 | }
|
48 | ;
|
49 |
|
50 | /**
|
51 | * This class follows the [Promises/A+](https://promisesaplus.com) and
|
52 | * [ES6](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) spec
|
53 | * with some extra helpers.
|
54 | * @param {Function} executor Function object with two arguments resolve, reject.
|
55 | * The first argument fulfills the promise, the second argument rejects it.
|
56 | * We can call these functions, once our operation is completed.
|
57 | */
|
58 | var Yaku = function Promise (executor) {
|
59 | var self = this,
|
60 | err;
|
61 |
|
62 | // "this._s" is the internal state of: pending, resolved or rejected
|
63 | // "this._v" is the internal value
|
64 |
|
65 | if (!isObject(self) || self._s !== $undefined)
|
66 | throw genTypeError($invalidThis);
|
67 |
|
68 | self._s = $pending;
|
69 |
|
70 | if (executor !== $noop) {
|
71 | if (!isFunction(executor))
|
72 | throw genTypeError($invalidArgument);
|
73 |
|
74 | err = genTryCatcher(executor)(
|
75 | genSettler(self, $resolved),
|
76 | genSettler(self, $rejected)
|
77 | );
|
78 |
|
79 | if (err === $tryErr)
|
80 | settlePromise(self, $rejected, err.e);
|
81 | }
|
82 | };
|
83 |
|
84 | Yaku["default"] = Yaku;
|
85 |
|
86 | extendPrototype(Yaku, {
|
87 | /**
|
88 | * Appends fulfillment and rejection handlers to the promise,
|
89 | * and returns a new promise resolving to the return value of the called handler.
|
90 | * @param {Function} onFulfilled Optional. Called when the Promise is resolved.
|
91 | * @param {Function} onRejected Optional. Called when the Promise is rejected.
|
92 | * @return {Yaku} It will return a new Yaku which will resolve or reject after
|
93 | * @example
|
94 | * the current Promise.
|
95 | * ```js
|
96 | * var Promise = require('yaku');
|
97 | * var p = Promise.resolve(10);
|
98 | *
|
99 | * p.then((v) => {
|
100 | * console.log(v);
|
101 | * });
|
102 | * ```
|
103 | */
|
104 | then: function then (onFulfilled, onRejected) {
|
105 | if (this._s === undefined) throw genTypeError();
|
106 |
|
107 | return addHandler(
|
108 | this,
|
109 | newCapablePromise(speciesConstructor(this, Yaku)),
|
110 | onFulfilled,
|
111 | onRejected
|
112 | );
|
113 | },
|
114 |
|
115 | /**
|
116 | * The `catch()` method returns a Promise and deals with rejected cases only.
|
117 | * It behaves the same as calling `Promise.prototype.then(undefined, onRejected)`.
|
118 | * @param {Function} onRejected A Function called when the Promise is rejected.
|
119 | * This function has one argument, the rejection reason.
|
120 | * @return {Yaku} A Promise that deals with rejected cases only.
|
121 | * @example
|
122 | * ```js
|
123 | * var Promise = require('yaku');
|
124 | * var p = Promise.reject(new Error("ERR"));
|
125 | *
|
126 | * p['catch']((v) => {
|
127 | * console.log(v);
|
128 | * });
|
129 | * ```
|
130 | */
|
131 | "catch": function (onRejected) {
|
132 | return this.then($undefined, onRejected);
|
133 | },
|
134 |
|
135 | /**
|
136 | * Register a callback to be invoked when a promise is settled (either fulfilled or rejected).
|
137 | * Similar with the try-catch-finally, it's often used for cleanup.
|
138 | * @param {Function} onFinally A Function called when the Promise is settled.
|
139 | * It will not receive any argument.
|
140 | * @return {Yaku} A Promise that will reject if onFinally throws an error or returns a rejected promise.
|
141 | * Else it will resolve previous promise's final state (either fulfilled or rejected).
|
142 | * @example
|
143 | * ```js
|
144 | * var Promise = require('yaku');
|
145 | * var p = Promise.reject(new Error("ERR"));
|
146 | *
|
147 | * p['catch']((v) => {
|
148 | * console.log(v);
|
149 | * });
|
150 | * ```
|
151 | */
|
152 | "finally": function (onFinally) {
|
153 | function eventually (value) {
|
154 | return Yaku.resolve(onFinally()).then(function () {
|
155 | return value;
|
156 | });
|
157 | }
|
158 |
|
159 | return this.then(eventually, eventually);
|
160 | },
|
161 |
|
162 | // The number of current promises that attach to this Yaku instance.
|
163 | _pCount: 0,
|
164 |
|
165 | // The parent Yaku.
|
166 | _pre: $null,
|
167 |
|
168 | // A unique type flag, it helps different versions of Yaku know each other.
|
169 | _Yaku: 1
|
170 | });
|
171 |
|
172 | /**
|
173 | * The `Promise.resolve(value)` method returns a Promise object that is resolved with the given value.
|
174 | * If the value is a thenable (i.e. has a then method), the returned promise will "follow" that thenable,
|
175 | * adopting its eventual state; otherwise the returned promise will be fulfilled with the value.
|
176 | * @param {Any} value Argument to be resolved by this Promise.
|
177 | * Can also be a Promise or a thenable to resolve.
|
178 | * @return {Yaku}
|
179 | * @example
|
180 | * ```js
|
181 | * var Promise = require('yaku');
|
182 | * var p = Promise.resolve(10);
|
183 | * ```
|
184 | */
|
185 | Yaku.resolve = function resolve (val) {
|
186 | return isYaku(val) ? val : settleWithX(newCapablePromise(this), val);
|
187 | };
|
188 |
|
189 | /**
|
190 | * The `Promise.reject(reason)` method returns a Promise object that is rejected with the given reason.
|
191 | * @param {Any} reason Reason why this Promise rejected.
|
192 | * @return {Yaku}
|
193 | * @example
|
194 | * ```js
|
195 | * var Promise = require('yaku');
|
196 | * var p = Promise.reject(new Error("ERR"));
|
197 | * ```
|
198 | */
|
199 | Yaku.reject = function reject (reason) {
|
200 | return settlePromise(newCapablePromise(this), $rejected, reason);
|
201 | };
|
202 |
|
203 | /**
|
204 | * The `Promise.race(iterable)` method returns a promise that resolves or rejects
|
205 | * as soon as one of the promises in the iterable resolves or rejects,
|
206 | * with the value or reason from that promise.
|
207 | * @param {iterable} iterable An iterable object, such as an Array.
|
208 | * @return {Yaku} The race function returns a Promise that is settled
|
209 | * the same way as the first passed promise to settle.
|
210 | * It resolves or rejects, whichever happens first.
|
211 | * @example
|
212 | * ```js
|
213 | * var Promise = require('yaku');
|
214 | * Promise.race([
|
215 | * 123,
|
216 | * Promise.resolve(0)
|
217 | * ])
|
218 | * .then((value) => {
|
219 | * console.log(value); // => 123
|
220 | * });
|
221 | * ```
|
222 | */
|
223 | Yaku.race = function race (iterable) {
|
224 | var self = this
|
225 | , p = newCapablePromise(self)
|
226 |
|
227 | , resolve = function (val) {
|
228 | settlePromise(p, $resolved, val);
|
229 | }
|
230 |
|
231 | , reject = function (val) {
|
232 | settlePromise(p, $rejected, val);
|
233 | }
|
234 |
|
235 | , ret = genTryCatcher(each)(iterable, function (v) {
|
236 | self.resolve(v).then(resolve, reject);
|
237 | });
|
238 |
|
239 | if (ret === $tryErr) return self.reject(ret.e);
|
240 |
|
241 | return p;
|
242 | };
|
243 |
|
244 | /**
|
245 | * The `Promise.all(iterable)` method returns a promise that resolves when
|
246 | * all of the promises in the iterable argument have resolved.
|
247 | *
|
248 | * The result is passed as an array of values from all the promises.
|
249 | * If something passed in the iterable array is not a promise,
|
250 | * it's converted to one by Promise.resolve. If any of the passed in promises rejects,
|
251 | * the all Promise immediately rejects with the value of the promise that rejected,
|
252 | * discarding all the other promises whether or not they have resolved.
|
253 | * @param {iterable} iterable An iterable object, such as an Array.
|
254 | * @return {Yaku}
|
255 | * @example
|
256 | * ```js
|
257 | * var Promise = require('yaku');
|
258 | * Promise.all([
|
259 | * 123,
|
260 | * Promise.resolve(0)
|
261 | * ])
|
262 | * .then((values) => {
|
263 | * console.log(values); // => [123, 0]
|
264 | * });
|
265 | * ```
|
266 | * @example
|
267 | * Use with iterable.
|
268 | * ```js
|
269 | * var Promise = require('yaku');
|
270 | * Promise.all((function * () {
|
271 | * yield 10;
|
272 | * yield new Promise(function (r) { setTimeout(r, 1000, "OK") });
|
273 | * })())
|
274 | * .then((values) => {
|
275 | * console.log(values); // => [123, 0]
|
276 | * });
|
277 | * ```
|
278 | */
|
279 | Yaku.all = function all (iterable) {
|
280 | var self = this
|
281 | , p1 = newCapablePromise(self)
|
282 | , res = []
|
283 | , ret
|
284 | ;
|
285 |
|
286 | function reject (reason) {
|
287 | settlePromise(p1, $rejected, reason);
|
288 | }
|
289 |
|
290 | ret = genTryCatcher(each)(iterable, function (item, i) {
|
291 | self.resolve(item).then(function (value) {
|
292 | res[i] = value;
|
293 | if (!--ret) settlePromise(p1, $resolved, res);
|
294 | }, reject);
|
295 | });
|
296 |
|
297 | if (ret === $tryErr) return self.reject(ret.e);
|
298 |
|
299 | if (!ret) settlePromise(p1, $resolved, []);
|
300 |
|
301 | return p1;
|
302 | };
|
303 |
|
304 | // To support browsers that don't support `Object.defineProperty`.
|
305 | genTryCatcher(function () {
|
306 | Object.defineProperty(Yaku, getSpecies(), {
|
307 | get: function () { return this; }
|
308 | });
|
309 | })();
|
310 |
|
311 | // ********************** Private **********************
|
312 |
|
313 | Yaku._Yaku = 1;
|
314 |
|
315 | /**
|
316 | * All static variable name will begin with `$`. Such as `$rejected`.
|
317 | * @private
|
318 | */
|
319 |
|
320 | // ******************************* Utils ********************************
|
321 |
|
322 | function getSpecies () {
|
323 | return Symbol[$species] || $speciesKey;
|
324 | }
|
325 |
|
326 | function extendPrototype (src, target) {
|
327 | for (var k in target) {
|
328 | src.prototype[k] = target[k];
|
329 | }
|
330 | return src;
|
331 | }
|
332 |
|
333 | function isObject (obj) {
|
334 | return obj && typeof obj === "object";
|
335 | }
|
336 |
|
337 | function isFunction (obj) {
|
338 | return typeof obj === "function";
|
339 | }
|
340 |
|
341 | function isInstanceOf (a, b) {
|
342 | return a instanceof b;
|
343 | }
|
344 |
|
345 | function ensureType (obj, fn, msg) {
|
346 | if (!fn(obj)) throw genTypeError(msg);
|
347 | }
|
348 |
|
349 | /**
|
350 | * Wrap a function into a try-catch.
|
351 | * @private
|
352 | * @return {Any | $tryErr}
|
353 | */
|
354 | function tryCatcher () {
|
355 | try {
|
356 | return $tryCatchFn.apply($tryCatchThis, arguments);
|
357 | } catch (e) {
|
358 | $tryErr.e = e;
|
359 | return $tryErr;
|
360 | }
|
361 | }
|
362 |
|
363 | /**
|
364 | * Generate a try-catch wrapped function.
|
365 | * @private
|
366 | * @param {Function} fn
|
367 | * @return {Function}
|
368 | */
|
369 | function genTryCatcher (fn, self) {
|
370 | $tryCatchFn = fn;
|
371 | $tryCatchThis = self;
|
372 | return tryCatcher;
|
373 | }
|
374 |
|
375 | /**
|
376 | * Generate a scheduler.
|
377 | * @private
|
378 | * @param {Integer} initQueueSize
|
379 | * @param {Function} fn `(Yaku, Value) ->` The schedule handler.
|
380 | * @return {Function} `(Yaku, Value) ->` The scheduler.
|
381 | */
|
382 | function genScheduler (initQueueSize, fn) {
|
383 | /**
|
384 | * All async promise will be scheduled in
|
385 | * here, so that they can be execute on the next tick.
|
386 | * @private
|
387 | */
|
388 | var fnQueue = Arr(initQueueSize)
|
389 | , fnQueueLen = 0;
|
390 |
|
391 | /**
|
392 | * Run all queued functions.
|
393 | * @private
|
394 | */
|
395 | function flush () {
|
396 | var i = 0;
|
397 | while (i < fnQueueLen) {
|
398 | fn(fnQueue[i], fnQueue[i + 1]);
|
399 | fnQueue[i++] = $undefined;
|
400 | fnQueue[i++] = $undefined;
|
401 | }
|
402 |
|
403 | fnQueueLen = 0;
|
404 | if (fnQueue.length > initQueueSize) fnQueue.length = initQueueSize;
|
405 | }
|
406 |
|
407 | return function (v, arg) {
|
408 | fnQueue[fnQueueLen++] = v;
|
409 | fnQueue[fnQueueLen++] = arg;
|
410 |
|
411 | if (fnQueueLen === 2) nextTick(flush);
|
412 | };
|
413 | }
|
414 |
|
415 | /**
|
416 | * Generate a iterator
|
417 | * @param {Any} obj
|
418 | * @private
|
419 | * @return {Object || TypeError}
|
420 | */
|
421 | function each (iterable, fn) {
|
422 | var len
|
423 | , i = 0
|
424 | , iter
|
425 | , item
|
426 | , ret
|
427 | ;
|
428 |
|
429 | if (!iterable) throw genTypeError($invalidArgument);
|
430 |
|
431 | var gen = iterable[Symbol[$iterator]];
|
432 | if (isFunction(gen))
|
433 | iter = gen.call(iterable);
|
434 | else if (isFunction(iterable.next)) {
|
435 | iter = iterable;
|
436 | }
|
437 | else if (isInstanceOf(iterable, Arr)) {
|
438 | len = iterable.length;
|
439 | while (i < len) {
|
440 | fn(iterable[i], i++);
|
441 | }
|
442 | return i;
|
443 | } else
|
444 | throw genTypeError($invalidArgument);
|
445 |
|
446 | while (!(item = iter.next()).done) {
|
447 | ret = genTryCatcher(fn)(item.value, i++);
|
448 | if (ret === $tryErr) {
|
449 | isFunction(iter[$return]) && iter[$return]();
|
450 | throw ret.e;
|
451 | }
|
452 | }
|
453 |
|
454 | return i;
|
455 | }
|
456 |
|
457 | /**
|
458 | * Generate type error object.
|
459 | * @private
|
460 | * @param {String} msg
|
461 | * @return {TypeError}
|
462 | */
|
463 | function genTypeError (msg) {
|
464 | return new TypeError(msg);
|
465 | }
|
466 |
|
467 | // *************************** Promise Helpers ****************************
|
468 |
|
469 | /**
|
470 | * Resolve the value returned by onFulfilled or onRejected.
|
471 | * @private
|
472 | * @param {Yaku} p1
|
473 | * @param {Yaku} p2
|
474 | */
|
475 | var scheduleHandler = genScheduler(999, function (p1, p2) {
|
476 | var x, handler;
|
477 |
|
478 | // 2.2.2
|
479 | // 2.2.3
|
480 | handler = p1._s ? p2._onFulfilled : p2._onRejected;
|
481 |
|
482 | // 2.2.7.3
|
483 | // 2.2.7.4
|
484 | if (handler === $undefined) {
|
485 | settlePromise(p2, p1._s, p1._v);
|
486 | return;
|
487 | }
|
488 |
|
489 | // 2.2.7.1
|
490 | x = genTryCatcher(callHanler)(handler, p1._v);
|
491 | if (x === $tryErr) {
|
492 | // 2.2.7.2
|
493 | settlePromise(p2, $rejected, x.e);
|
494 | return;
|
495 | }
|
496 |
|
497 | settleWithX(p2, x);
|
498 | });
|
499 |
|
500 | var scheduleUnhandledRejection = genScheduler(9, function (p) {
|
501 | if (!hashOnRejected(p)) {
|
502 | p[$unhandled] = 1;
|
503 | emitEvent($unhandledRejection, p);
|
504 | }
|
505 | });
|
506 |
|
507 | function emitEvent (name, p) {
|
508 | var browserEventName = "on" + name.toLowerCase()
|
509 | , browserHandler = root[browserEventName];
|
510 |
|
511 | if (process && process.listeners(name).length)
|
512 | name === $unhandledRejection ?
|
513 | process.emit(name, p._v, p) : process.emit(name, p);
|
514 | else if (browserHandler)
|
515 | browserHandler({ reason: p._v, promise: p });
|
516 | }
|
517 |
|
518 | function isYaku (val) { return val && val._Yaku; }
|
519 |
|
520 | function newCapablePromise (Constructor) {
|
521 | if (isYaku(Constructor)) return new Constructor($noop);
|
522 |
|
523 | var p, r, j;
|
524 | p = new Constructor(function (resolve, reject) {
|
525 | if (p) throw genTypeError();
|
526 |
|
527 | r = resolve;
|
528 | j = reject;
|
529 | });
|
530 |
|
531 | ensureType(r, isFunction);
|
532 | ensureType(j, isFunction);
|
533 |
|
534 | return p;
|
535 | }
|
536 |
|
537 | /**
|
538 | * It will produce a settlePromise function to user.
|
539 | * Such as the resolve and reject in this `new Yaku (resolve, reject) ->`.
|
540 | * @private
|
541 | * @param {Yaku} self
|
542 | * @param {Integer} state The value is one of `$pending`, `$resolved` or `$rejected`.
|
543 | * @return {Function} `(value) -> undefined` A resolve or reject function.
|
544 | */
|
545 | function genSettler (self, state) {
|
546 | return function (value) {
|
547 | if (state === $resolved)
|
548 | settleWithX(self, value);
|
549 | else
|
550 | settlePromise(self, state, value);
|
551 | };
|
552 | }
|
553 |
|
554 | /**
|
555 | * Link the promise1 to the promise2.
|
556 | * @private
|
557 | * @param {Yaku} p1
|
558 | * @param {Yaku} p2
|
559 | * @param {Function} onFulfilled
|
560 | * @param {Function} onRejected
|
561 | */
|
562 | function addHandler (p1, p2, onFulfilled, onRejected) {
|
563 | // 2.2.1
|
564 | if (isFunction(onFulfilled))
|
565 | p2._onFulfilled = onFulfilled;
|
566 | if (isFunction(onRejected)) {
|
567 | if (p1[$unhandled]) emitEvent($rejectionHandled, p1);
|
568 |
|
569 | p2._onRejected = onRejected;
|
570 | }
|
571 |
|
572 | p1[p1._pCount++] = p2;
|
573 |
|
574 | // 2.2.6
|
575 | if (p1._s !== $pending)
|
576 | scheduleHandler(p1, p2);
|
577 |
|
578 | // 2.2.7
|
579 | return p2;
|
580 | }
|
581 |
|
582 | // iterate tree
|
583 | function hashOnRejected (node) {
|
584 | // A node shouldn't be checked twice.
|
585 | if (node._umark)
|
586 | return true;
|
587 | else
|
588 | node._umark = true;
|
589 |
|
590 | var i = 0
|
591 | , len = node._pCount
|
592 | , child;
|
593 |
|
594 | while (i < len) {
|
595 | child = node[i++];
|
596 | if (child._onRejected || hashOnRejected(child)) return true;
|
597 | }
|
598 | }
|
599 |
|
600 | function callHanler (handler, value) {
|
601 | // 2.2.5
|
602 | return handler(value);
|
603 | }
|
604 |
|
605 | /**
|
606 | * Resolve or reject a promise.
|
607 | * @private
|
608 | * @param {Yaku} p
|
609 | * @param {Integer} state
|
610 | * @param {Any} value
|
611 | */
|
612 | function settlePromise (p, state, value) {
|
613 | var i = 0
|
614 | , len = p._pCount;
|
615 |
|
616 | // 2.1.2
|
617 | // 2.1.3
|
618 | if (p._s === $pending) {
|
619 | // 2.1.1.1
|
620 | p._s = state;
|
621 | p._v = value;
|
622 |
|
623 | if (state === $rejected) {
|
624 | scheduleUnhandledRejection(p);
|
625 | }
|
626 |
|
627 | // 2.2.4
|
628 | while (i < len) {
|
629 | scheduleHandler(p, p[i++]);
|
630 | }
|
631 | }
|
632 |
|
633 | return p;
|
634 | }
|
635 |
|
636 | /**
|
637 | * Resolve or reject promise with value x. The x can also be a thenable.
|
638 | * @private
|
639 | * @param {Yaku} p
|
640 | * @param {Any | Thenable} x A normal value or a thenable.
|
641 | */
|
642 | function settleWithX (p, x) {
|
643 | // 2.3.1
|
644 | if (x === p && x) {
|
645 | settlePromise(p, $rejected, genTypeError($promiseCircularChain));
|
646 | return p;
|
647 | }
|
648 |
|
649 | // 2.3.2
|
650 | // 2.3.3
|
651 | if (x !== $null && (isFunction(x) || isObject(x))) {
|
652 | // 2.3.2.1
|
653 | var xthen = genTryCatcher(getThen)(x);
|
654 |
|
655 | if (xthen === $tryErr) {
|
656 | // 2.3.3.2
|
657 | settlePromise(p, $rejected, xthen.e);
|
658 | return p;
|
659 | }
|
660 |
|
661 | if (isFunction(xthen)) {
|
662 | // Fix https://bugs.chromium.org/p/v8/issues/detail?id=4162
|
663 | if (isYaku(x))
|
664 | settleXthen(p, x, xthen);
|
665 | else
|
666 | nextTick(function () {
|
667 | settleXthen(p, x, xthen);
|
668 | });
|
669 | } else
|
670 | // 2.3.3.4
|
671 | settlePromise(p, $resolved, x);
|
672 | } else
|
673 | // 2.3.4
|
674 | settlePromise(p, $resolved, x);
|
675 |
|
676 | return p;
|
677 | }
|
678 |
|
679 | /**
|
680 | * Try to get a promise's then method.
|
681 | * @private
|
682 | * @param {Thenable} x
|
683 | * @return {Function}
|
684 | */
|
685 | function getThen (x) { return x.then; }
|
686 |
|
687 | /**
|
688 | * Resolve then with its promise.
|
689 | * @private
|
690 | * @param {Yaku} p
|
691 | * @param {Thenable} x
|
692 | * @param {Function} xthen
|
693 | */
|
694 | function settleXthen (p, x, xthen) {
|
695 | // 2.3.3.3
|
696 | var err = genTryCatcher(xthen, x)(function (y) {
|
697 | // 2.3.3.3.3
|
698 | // 2.3.3.3.1
|
699 | x && (x = $null, settleWithX(p, y));
|
700 | }, function (r) {
|
701 | // 2.3.3.3.3
|
702 | // 2.3.3.3.2
|
703 | x && (x = $null, settlePromise(p, $rejected, r));
|
704 | });
|
705 |
|
706 | // 2.3.3.3.4.1
|
707 | if (err === $tryErr && x) {
|
708 | // 2.3.3.3.4.2
|
709 | settlePromise(p, $rejected, err.e);
|
710 | x = $null;
|
711 | }
|
712 | }
|
713 |
|
714 | try {
|
715 | module.exports = Yaku;
|
716 | } catch (e) {
|
717 | root.Yaku = Yaku;
|
718 | }
|
719 | })();
|