Best JavaScript code snippet using cavy
es6-promise.js
Source:es6-promise.js  
...130    function lib$es6$promise$then$$then(onFulfillment, onRejection) {131      var parent = this;132      var child = new this.constructor(lib$es6$promise$$internal$$noop);133      if (child[lib$es6$promise$$internal$$PROMISE_ID] === undefined) {134        lib$es6$promise$$internal$$makePromise(child);135      }136      var state = parent._state;137      if (state) {138        var callback = arguments[state - 1];139        lib$es6$promise$asap$$asap(function(){140          lib$es6$promise$$internal$$invokeCallback(state, child, callback, parent._result);141        });142      } else {143        lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection);144      }145      return child;146    }147    var lib$es6$promise$then$$default = lib$es6$promise$then$$then;148    function lib$es6$promise$promise$resolve$$resolve(object) {149      /*jshint validthis:true */150      var Constructor = this;151      if (object && typeof object === 'object' && object.constructor === Constructor) {152        return object;153      }154      var promise = new Constructor(lib$es6$promise$$internal$$noop);155      lib$es6$promise$$internal$$resolve(promise, object);156      return promise;157    }158    var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve;159    var lib$es6$promise$$internal$$PROMISE_ID = Math.random().toString(36).substring(16);160    function lib$es6$promise$$internal$$noop() {}161    var lib$es6$promise$$internal$$PENDING   = void 0;162    var lib$es6$promise$$internal$$FULFILLED = 1;163    var lib$es6$promise$$internal$$REJECTED  = 2;164    var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject();165    function lib$es6$promise$$internal$$selfFulfillment() {166      return new TypeError("You cannot resolve a promise with itself");167    }168    function lib$es6$promise$$internal$$cannotReturnOwn() {169      return new TypeError('A promises callback cannot return that same promise.');170    }171    function lib$es6$promise$$internal$$getThen(promise) {172      try {173        return promise.then;174      } catch(error) {175        lib$es6$promise$$internal$$GET_THEN_ERROR.error = error;176        return lib$es6$promise$$internal$$GET_THEN_ERROR;177      }178    }179    function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {180      try {181        then.call(value, fulfillmentHandler, rejectionHandler);182      } catch(e) {183        return e;184      }185    }186    function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) {187       lib$es6$promise$asap$$asap(function(promise) {188        var sealed = false;189        var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) {190          if (sealed) { return; }191          sealed = true;192          if (thenable !== value) {193            lib$es6$promise$$internal$$resolve(promise, value);194          } else {195            lib$es6$promise$$internal$$fulfill(promise, value);196          }197        }, function(reason) {198          if (sealed) { return; }199          sealed = true;200          lib$es6$promise$$internal$$reject(promise, reason);201        }, 'Settle: ' + (promise._label || ' unknown promise'));202        if (!sealed && error) {203          sealed = true;204          lib$es6$promise$$internal$$reject(promise, error);205        }206      }, promise);207    }208    function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) {209      if (thenable._state === lib$es6$promise$$internal$$FULFILLED) {210        lib$es6$promise$$internal$$fulfill(promise, thenable._result);211      } else if (thenable._state === lib$es6$promise$$internal$$REJECTED) {212        lib$es6$promise$$internal$$reject(promise, thenable._result);213      } else {214        lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) {215          lib$es6$promise$$internal$$resolve(promise, value);216        }, function(reason) {217          lib$es6$promise$$internal$$reject(promise, reason);218        });219      }220    }221    function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable, then) {222      if (maybeThenable.constructor === promise.constructor &&223          then === lib$es6$promise$then$$default &&224          constructor.resolve === lib$es6$promise$promise$resolve$$default) {225        lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable);226      } else {227        if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) {228          lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error);229        } else if (then === undefined) {230          lib$es6$promise$$internal$$fulfill(promise, maybeThenable);231        } else if (lib$es6$promise$utils$$isFunction(then)) {232          lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then);233        } else {234          lib$es6$promise$$internal$$fulfill(promise, maybeThenable);235        }236      }237    }238    function lib$es6$promise$$internal$$resolve(promise, value) {239      if (promise === value) {240        lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFulfillment());241      } else if (lib$es6$promise$utils$$objectOrFunction(value)) {242        lib$es6$promise$$internal$$handleMaybeThenable(promise, value, lib$es6$promise$$internal$$getThen(value));243      } else {244        lib$es6$promise$$internal$$fulfill(promise, value);245      }246    }247    function lib$es6$promise$$internal$$publishRejection(promise) {248      if (promise._onerror) {249        promise._onerror(promise._result);250      }251      lib$es6$promise$$internal$$publish(promise);252    }253    function lib$es6$promise$$internal$$fulfill(promise, value) {254      if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }255      promise._result = value;256      promise._state = lib$es6$promise$$internal$$FULFILLED;257      if (promise._subscribers.length !== 0) {258        lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise);259      }260    }261    function lib$es6$promise$$internal$$reject(promise, reason) {262      if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }263      promise._state = lib$es6$promise$$internal$$REJECTED;264      promise._result = reason;265      lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise);266    }267    function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) {268      var subscribers = parent._subscribers;269      var length = subscribers.length;270      parent._onerror = null;271      subscribers[length] = child;272      subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment;273      subscribers[length + lib$es6$promise$$internal$$REJECTED]  = onRejection;274      if (length === 0 && parent._state) {275        lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent);276      }277    }278    function lib$es6$promise$$internal$$publish(promise) {279      var subscribers = promise._subscribers;280      var settled = promise._state;281      if (subscribers.length === 0) { return; }282      var child, callback, detail = promise._result;283      for (var i = 0; i < subscribers.length; i += 3) {284        child = subscribers[i];285        callback = subscribers[i + settled];286        if (child) {287          lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail);288        } else {289          callback(detail);290        }291      }292      promise._subscribers.length = 0;293    }294    function lib$es6$promise$$internal$$ErrorObject() {295      this.error = null;296    }297    var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject();298    function lib$es6$promise$$internal$$tryCatch(callback, detail) {299      try {300        return callback(detail);301      } catch(e) {302        lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e;303        return lib$es6$promise$$internal$$TRY_CATCH_ERROR;304      }305    }306    function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) {307      var hasCallback = lib$es6$promise$utils$$isFunction(callback),308          value, error, succeeded, failed;309      if (hasCallback) {310        value = lib$es6$promise$$internal$$tryCatch(callback, detail);311        if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) {312          failed = true;313          error = value.error;314          value = null;315        } else {316          succeeded = true;317        }318        if (promise === value) {319          lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn());320          return;321        }322      } else {323        value = detail;324        succeeded = true;325      }326      if (promise._state !== lib$es6$promise$$internal$$PENDING) {327        // noop328      } else if (hasCallback && succeeded) {329        lib$es6$promise$$internal$$resolve(promise, value);330      } else if (failed) {331        lib$es6$promise$$internal$$reject(promise, error);332      } else if (settled === lib$es6$promise$$internal$$FULFILLED) {333        lib$es6$promise$$internal$$fulfill(promise, value);334      } else if (settled === lib$es6$promise$$internal$$REJECTED) {335        lib$es6$promise$$internal$$reject(promise, value);336      }337    }338    function lib$es6$promise$$internal$$initializePromise(promise, resolver) {339      try {340        resolver(function resolvePromise(value){341          lib$es6$promise$$internal$$resolve(promise, value);342        }, function rejectPromise(reason) {343          lib$es6$promise$$internal$$reject(promise, reason);344        });345      } catch(e) {346        lib$es6$promise$$internal$$reject(promise, e);347      }348    }349    var lib$es6$promise$$internal$$id = 0;350    function lib$es6$promise$$internal$$nextId() {351      return lib$es6$promise$$internal$$id++;352    }353    function lib$es6$promise$$internal$$makePromise(promise) {354      promise[lib$es6$promise$$internal$$PROMISE_ID] = lib$es6$promise$$internal$$id++;355      promise._state = undefined;356      promise._result = undefined;357      promise._subscribers = [];358    }359    function lib$es6$promise$promise$all$$all(entries) {360      return new lib$es6$promise$enumerator$$default(this, entries).promise;361    }362    var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all;363    function lib$es6$promise$promise$race$$race(entries) {364      /*jshint validthis:true */365      var Constructor = this;366      if (!lib$es6$promise$utils$$isArray(entries)) {367        return new Constructor(function(resolve, reject) {368          reject(new TypeError('You must pass an array to race.'));369        });370      } else {371        return new Constructor(function(resolve, reject) {372          var length = entries.length;373          for (var i = 0; i < length; i++) {374            Constructor.resolve(entries[i]).then(resolve, reject);375          }376        });377      }378    }379    var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race;380    function lib$es6$promise$promise$reject$$reject(reason) {381      /*jshint validthis:true */382      var Constructor = this;383      var promise = new Constructor(lib$es6$promise$$internal$$noop);384      lib$es6$promise$$internal$$reject(promise, reason);385      return promise;386    }387    var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject;388    function lib$es6$promise$promise$$needsResolver() {389      throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');390    }391    function lib$es6$promise$promise$$needsNew() {392      throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");393    }394    var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise;395    /**396      Promise objects represent the eventual result of an asynchronous operation. The397      primary way of interacting with a promise is through its `then` method, which398      registers callbacks to receive either a promise's eventual value or the reason399      why the promise cannot be fulfilled.400      Terminology401      -----------402      - `promise` is an object or function with a `then` method whose behavior conforms to this specification.403      - `thenable` is an object or function that defines a `then` method.404      - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).405      - `exception` is a value that is thrown using the throw statement.406      - `reason` is a value that indicates why a promise was rejected.407      - `settled` the final resting state of a promise, fulfilled or rejected.408      A promise can be in one of three states: pending, fulfilled, or rejected.409      Promises that are fulfilled have a fulfillment value and are in the fulfilled410      state.  Promises that are rejected have a rejection reason and are in the411      rejected state.  A fulfillment value is never a thenable.412      Promises can also be said to *resolve* a value.  If this value is also a413      promise, then the original promise's settled state will match the value's414      settled state.  So a promise that *resolves* a promise that rejects will415      itself reject, and a promise that *resolves* a promise that fulfills will416      itself fulfill.417      Basic Usage:418      ------------419      ```js420      var promise = new Promise(function(resolve, reject) {421        // on success422        resolve(value);423        // on failure424        reject(reason);425      });426      promise.then(function(value) {427        // on fulfillment428      }, function(reason) {429        // on rejection430      });431      ```432      Advanced Usage:433      ---------------434      Promises shine when abstracting away asynchronous interactions such as435      `XMLHttpRequest`s.436      ```js437      function getJSON(url) {438        return new Promise(function(resolve, reject){439          var xhr = new XMLHttpRequest();440          xhr.open('GET', url);441          xhr.onreadystatechange = handler;442          xhr.responseType = 'json';443          xhr.setRequestHeader('Accept', 'application/json');444          xhr.send();445          function handler() {446            if (this.readyState === this.DONE) {447              if (this.status === 200) {448                resolve(this.response);449              } else {450                reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));451              }452            }453          };454        });455      }456      getJSON('/posts.json').then(function(json) {457        // on fulfillment458      }, function(reason) {459        // on rejection460      });461      ```462      Unlike callbacks, promises are great composable primitives.463      ```js464      Promise.all([465        getJSON('/posts'),466        getJSON('/comments')467      ]).then(function(values){468        values[0] // => postsJSON469        values[1] // => commentsJSON470        return values;471      });472      ```473      @class Promise474      @param {function} resolver475      Useful for tooling.476      @constructor477    */478    function lib$es6$promise$promise$$Promise(resolver) {479      this[lib$es6$promise$$internal$$PROMISE_ID] = lib$es6$promise$$internal$$nextId();480      this._result = this._state = undefined;481      this._subscribers = [];482      if (lib$es6$promise$$internal$$noop !== resolver) {483        typeof resolver !== 'function' && lib$es6$promise$promise$$needsResolver();484        this instanceof lib$es6$promise$promise$$Promise ? lib$es6$promise$$internal$$initializePromise(this, resolver) : lib$es6$promise$promise$$needsNew();485      }486    }487    lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default;488    lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default;489    lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default;490    lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default;491    lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler;492    lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap;493    lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap;494    lib$es6$promise$promise$$Promise.prototype = {495      constructor: lib$es6$promise$promise$$Promise,496    /**497      The primary way of interacting with a promise is through its `then` method,498      which registers callbacks to receive either a promise's eventual value or the499      reason why the promise cannot be fulfilled.500      ```js501      findUser().then(function(user){502        // user is available503      }, function(reason){504        // user is unavailable, and you are given the reason why505      });506      ```507      Chaining508      --------509      The return value of `then` is itself a promise.  This second, 'downstream'510      promise is resolved with the return value of the first promise's fulfillment511      or rejection handler, or rejected if the handler throws an exception.512      ```js513      findUser().then(function (user) {514        return user.name;515      }, function (reason) {516        return 'default name';517      }).then(function (userName) {518        // If `findUser` fulfilled, `userName` will be the user's name, otherwise it519        // will be `'default name'`520      });521      findUser().then(function (user) {522        throw new Error('Found user, but still unhappy');523      }, function (reason) {524        throw new Error('`findUser` rejected and we're unhappy');525      }).then(function (value) {526        // never reached527      }, function (reason) {528        // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.529        // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.530      });531      ```532      If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.533      ```js534      findUser().then(function (user) {535        throw new PedagogicalException('Upstream error');536      }).then(function (value) {537        // never reached538      }).then(function (value) {539        // never reached540      }, function (reason) {541        // The `PedgagocialException` is propagated all the way down to here542      });543      ```544      Assimilation545      ------------546      Sometimes the value you want to propagate to a downstream promise can only be547      retrieved asynchronously. This can be achieved by returning a promise in the548      fulfillment or rejection handler. The downstream promise will then be pending549      until the returned promise is settled. This is called *assimilation*.550      ```js551      findUser().then(function (user) {552        return findCommentsByAuthor(user);553      }).then(function (comments) {554        // The user's comments are now available555      });556      ```557      If the assimliated promise rejects, then the downstream promise will also reject.558      ```js559      findUser().then(function (user) {560        return findCommentsByAuthor(user);561      }).then(function (comments) {562        // If `findCommentsByAuthor` fulfills, we'll have the value here563      }, function (reason) {564        // If `findCommentsByAuthor` rejects, we'll have the reason here565      });566      ```567      Simple Example568      --------------569      Synchronous Example570      ```javascript571      var result;572      try {573        result = findResult();574        // success575      } catch(reason) {576        // failure577      }578      ```579      Errback Example580      ```js581      findResult(function(result, err){582        if (err) {583          // failure584        } else {585          // success586        }587      });588      ```589      Promise Example;590      ```javascript591      findResult().then(function(result){592        // success593      }, function(reason){594        // failure595      });596      ```597      Advanced Example598      --------------599      Synchronous Example600      ```javascript601      var author, books;602      try {603        author = findAuthor();604        books  = findBooksByAuthor(author);605        // success606      } catch(reason) {607        // failure608      }609      ```610      Errback Example611      ```js612      function foundBooks(books) {613      }614      function failure(reason) {615      }616      findAuthor(function(author, err){617        if (err) {618          failure(err);619          // failure620        } else {621          try {622            findBoooksByAuthor(author, function(books, err) {623              if (err) {624                failure(err);625              } else {626                try {627                  foundBooks(books);628                } catch(reason) {629                  failure(reason);630                }631              }632            });633          } catch(error) {634            failure(err);635          }636          // success637        }638      });639      ```640      Promise Example;641      ```javascript642      findAuthor().643        then(findBooksByAuthor).644        then(function(books){645          // found books646      }).catch(function(reason){647        // something went wrong648      });649      ```650      @method then651      @param {Function} onFulfilled652      @param {Function} onRejected653      Useful for tooling.654      @return {Promise}655    */656      then: lib$es6$promise$then$$default,657    /**658      `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same659      as the catch block of a try/catch statement.660      ```js661      function findAuthor(){662        throw new Error('couldn't find that author');663      }664      // synchronous665      try {666        findAuthor();667      } catch(reason) {668        // something went wrong669      }670      // async with promises671      findAuthor().catch(function(reason){672        // something went wrong673      });674      ```675      @method catch676      @param {Function} onRejection677      Useful for tooling.678      @return {Promise}679    */680      'catch': function(onRejection) {681        return this.then(null, onRejection);682      }683    };684    var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator;685    function lib$es6$promise$enumerator$$Enumerator(Constructor, input) {686      this._instanceConstructor = Constructor;687      this.promise = new Constructor(lib$es6$promise$$internal$$noop);688      if (!this.promise[lib$es6$promise$$internal$$PROMISE_ID]) {689        lib$es6$promise$$internal$$makePromise(this.promise);690      }691      if (Array.isArray(input)) {692        this._input     = input;693        this.length     = input.length;694        this._remaining = input.length;695        this._result = new Array(this.length);696        if (this.length === 0) {697          lib$es6$promise$$internal$$fulfill(this.promise, this._result);698        } else {699          this.length = this.length || 0;700          this._enumerate();701          if (this._remaining === 0) {702            lib$es6$promise$$internal$$fulfill(this.promise, this._result);703          }...promises.js
Source:promises.js  
...33var symbolIterator = Symbol.iterator;34(function() {35  // Test before clearing global (fails otherwise)36  assertEquals("[object Promise]",37      Object.prototype.toString.call(new Promise(function() {})));38})();39function clear(o) {40  if (o === null || (typeof o !== 'object' && typeof o !== 'function')) return41  clear(o.__proto__)42  var properties = getOwnPropertyNames(o)43  for (var i in properties) {44    // Do not clobber Object.prototype.toString, which is used by tests.45    if (properties[i] === "toString") continue;46    clearProp(o, properties[i])47  }48}49function clearProp(o, name) {50  var poisoned = {caller: 0, callee: 0, arguments: 0}51  try {52    var x = o[name]53    o[name] = undefined54    clear(x)55  } catch(e) {} // assertTrue(name in poisoned) }56}57// Find intrinsics and null them out.58var globals = Object.getOwnPropertyNames(this)59var whitelist = {60  Promise: true,61  TypeError: true,62  String: true,63  JSON: true,64  Error: true,65  MjsUnitAssertionError: true66};67for (var i in globals) {68  var name = globals[i]69  if (name in whitelist || name[0] === name[0].toLowerCase()) delete globals[i]70}71for (var i in globals) {72  if (globals[i]) clearProp(this, globals[i])73}74var asyncAssertsExpected = 0;75function assertAsyncRan() { ++asyncAssertsExpected }76function assertAsync(b, s) {77  if (b) {78    print(s, "succeeded")79  } else {80    %AbortJS(s + " FAILED!")  // Simply throwing here will have no effect.81  }82  --asyncAssertsExpected83}84function assertLater(f, name) {85  assertFalse(f()); // should not be true synchronously86  ++asyncAssertsExpected;87  var iterations = 0;88  function runAssertion() {89    if (f()) {90      print(name, "succeeded");91      --asyncAssertsExpected;92    } else if (iterations++ < 10) {93      %EnqueueMicrotask(runAssertion);94    } else {95      %AbortJS(name + " FAILED!");96    }97  }98  %EnqueueMicrotask(runAssertion);99}100function assertAsyncDone(iteration) {101  var iteration = iteration || 0;102  %EnqueueMicrotask(function() {103    if (asyncAssertsExpected === 0)104      assertAsync(true, "all")105    else if (iteration > 10)  // Shouldn't take more.106      assertAsync(false, "all... " + asyncAssertsExpected)107    else108      assertAsyncDone(iteration + 1)109  });110}111(function() {112  assertThrows(function() { Promise(function() {}) }, TypeError)113})();114(function() {115  assertTrue(new Promise(function() {}) instanceof Promise)116})();117(function() {118  assertThrows(function() { new Promise(5) }, TypeError)119})();120(function() {121  assertDoesNotThrow(function() { new Promise(function() { throw 5 }) })122})();123(function() {124  (new Promise(function() { throw 5 })).chain(125    assertUnreachable,126    function(r) { assertAsync(r === 5, "new-throw") }127  )128  assertAsyncRan()129})();130(function() {131  Promise.accept(5);132  Promise.accept(5).chain(undefined, assertUnreachable).chain(133    function(x) { assertAsync(x === 5, "resolved/chain-nohandler") },134    assertUnreachable135  )136  assertAsyncRan()137})();138(function() {139  Promise.reject(5).chain(assertUnreachable, undefined).chain(140    assertUnreachable,141    function(r) { assertAsync(r === 5, "rejected/chain-nohandler") }142  )143  assertAsyncRan()144})();145(function() {146  Promise.accept(5).then(undefined, assertUnreachable).chain(147    function(x) { assertAsync(x === 5, "resolved/then-nohandler-undefined") },148    assertUnreachable149  )150  assertAsyncRan()151  Promise.accept(6).then(null, assertUnreachable).chain(152    function(x) { assertAsync(x === 6, "resolved/then-nohandler-null") },153    assertUnreachable154  )155  assertAsyncRan()156})();157(function() {158  Promise.reject(5).then(assertUnreachable, undefined).chain(159    assertUnreachable,160    function(r) { assertAsync(r === 5, "rejected/then-nohandler-undefined") }161  )162  assertAsyncRan()163  Promise.reject(6).then(assertUnreachable, null).chain(164    assertUnreachable,165    function(r) { assertAsync(r === 6, "rejected/then-nohandler-null") }166  )167  assertAsyncRan()168})();169(function() {170  var p1 = Promise.accept(5)171  var p2 = Promise.accept(p1)172  var p3 = Promise.accept(p2)173  // Note: Chain now has then-style semantics, here and in future tests.174  p3.chain(175    function(x) { assertAsync(x === 5, "resolved/chain") },176    assertUnreachable177  )178  assertAsyncRan()179})();180(function() {181  var p1 = Promise.accept(5)182  var p2 = Promise.accept(p1)183  var p3 = Promise.accept(p2)184  p3.then(185    function(x) { assertAsync(x === 5, "resolved/then") },186    assertUnreachable187  )188  assertAsyncRan()189})();190(function() {191  var p1 = Promise.reject(5)192  var p2 = Promise.accept(p1)193  var p3 = Promise.accept(p2)194  p3.chain(195    assertUnreachable,196    function(x) { assertAsync(x === 5, "rejected/chain") }197  )198  assertAsyncRan()199})();200(function() {201  var p1 = Promise.reject(5)202  var p2 = Promise.accept(p1)203  var p3 = Promise.accept(p2)204  p3.then(205    assertUnreachable,206    function(x) { assertAsync(x === 5, "rejected/then") }207  )208  assertAsyncRan()209})();210(function() {211  var p1 = Promise.accept(5)212  var p2 = Promise.accept(p1)213  var p3 = Promise.accept(p2)214  p3.chain(function(x) { return x }, assertUnreachable).chain(215    function(x) { assertAsync(x === 5, "resolved/chain/chain") },216    assertUnreachable217  )218  assertAsyncRan()219})();220(function() {221  var p1 = Promise.accept(5)222  var p2 = Promise.accept(p1)223  var p3 = Promise.accept(p2)224  p3.chain(function(x) { return x }, assertUnreachable).then(225    function(x) { assertAsync(x === 5, "resolved/chain/then") },226    assertUnreachable227  )228  assertAsyncRan()229})();230(function() {231  var p1 = Promise.accept(5)232  var p2 = Promise.accept(p1)233  var p3 = Promise.accept(p2)234  p3.chain(function(x) { return 6 }, assertUnreachable).chain(235    function(x) { assertAsync(x === 6, "resolved/chain/chain2") },236    assertUnreachable237  )238  assertAsyncRan()239})();240(function() {241  var p1 = Promise.accept(5)242  var p2 = Promise.accept(p1)243  var p3 = Promise.accept(p2)244  p3.chain(function(x) { return 6 }, assertUnreachable).then(245    function(x) { assertAsync(x === 6, "resolved/chain/then2") },246    assertUnreachable247  )248  assertAsyncRan()249})();250(function() {251  var p1 = Promise.accept(5)252  var p2 = Promise.accept(p1)253  var p3 = Promise.accept(p2)254  p3.then(function(x) { return x + 1 }, assertUnreachable).chain(255    function(x) { assertAsync(x === 6, "resolved/then/chain") },256    assertUnreachable257  )258  assertAsyncRan()259})();260(function() {261  var p1 = Promise.accept(5)262  var p2 = Promise.accept(p1)263  var p3 = Promise.accept(p2)264  p3.then(function(x) { return x + 1 }, assertUnreachable).then(265    function(x) { assertAsync(x === 6, "resolved/then/then") },266    assertUnreachable267  )268  assertAsyncRan()269})();270(function() {271  var p1 = Promise.accept(5)272  var p2 = Promise.accept(p1)273  var p3 = Promise.accept(p2)274  p3.then(function(x){ return Promise.accept(x+1) }, assertUnreachable).chain(275    function(x) { assertAsync(x === 6, "resolved/then/chain2") },276    assertUnreachable277  )278  assertAsyncRan()279})();280(function() {281  var p1 = Promise.accept(5)282  var p2 = Promise.accept(p1)283  var p3 = Promise.accept(p2)284  p3.then(function(x) { return Promise.accept(x+1) }, assertUnreachable).then(285    function(x) { assertAsync(x === 6, "resolved/then/then2") },286    assertUnreachable287  )288  assertAsyncRan()289})();290(function() {291  var p1 = Promise.accept(5)292  var p2 = Promise.accept(p1)293  var p3 = Promise.accept(p2)294  p3.chain(function(x) { throw 6 }, assertUnreachable).chain(295    assertUnreachable,296    function(x) { assertAsync(x === 6, "resolved/chain-throw/chain") }297  )298  assertAsyncRan()299})();300(function() {301  var p1 = Promise.accept(5)302  var p2 = Promise.accept(p1)303  var p3 = Promise.accept(p2)304  p3.chain(function(x) { throw 6 }, assertUnreachable).then(305    assertUnreachable,306    function(x) { assertAsync(x === 6, "resolved/chain-throw/then") }307  )308  assertAsyncRan()309})();310(function() {311  var p1 = Promise.accept(5)312  var p2 = Promise.accept(p1)313  var p3 = Promise.accept(p2)314  p3.then(function(x) { throw 6 }, assertUnreachable).chain(315    assertUnreachable,316    function(x) { assertAsync(x === 6, "resolved/then-throw/chain") }317  )318  assertAsyncRan()319})();320(function() {321  var p1 = Promise.accept(5)322  var p2 = Promise.accept(p1)323  var p3 = Promise.accept(p2)324  p3.then(function(x) { throw 6 }, assertUnreachable).then(325    assertUnreachable,326    function(x) { assertAsync(x === 6, "resolved/then-throw/then") }327  )328  assertAsyncRan()329})();330(function() {331  var p1 = Promise.accept(5)332  var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}333  var p3 = Promise.accept(p2)334  p3.chain(335    function(x) { assertAsync(x === 5, "resolved/thenable/chain") },336    assertUnreachable337  )338  assertAsyncRan()339})();340(function() {341  var p1 = Promise.accept(5)342  var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}343  var p3 = Promise.accept(p2)344  p3.then(345    function(x) { assertAsync(x === 5, "resolved/thenable/then") },346    assertUnreachable347  )348  assertAsyncRan()349})();350(function() {351  var p1 = Promise.reject(5)352  var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}353  var p3 = Promise.accept(p2)354  p3.chain(355    assertUnreachable,356    function(x) { assertAsync(x === 5, "rejected/thenable/chain") }357  )358  assertAsyncRan()359})();360(function() {361  var p1 = Promise.reject(5)362  var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}363  var p3 = Promise.accept(p2)364  p3.then(365    assertUnreachable,366    function(x) { assertAsync(x === 5, "rejected/thenable/then") }367  )368  assertAsyncRan()369})();370(function() {371  var deferred = Promise.defer()372  var p1 = deferred.promise373  var p2 = Promise.accept(p1)374  var p3 = Promise.accept(p2)375  p3.chain(376    function(x) { assertAsync(x === 5, "chain/resolve") },377    assertUnreachable378  )379  deferred.resolve(5)380  assertAsyncRan()381})();382(function() {383  var deferred = Promise.defer()384  var p1 = deferred.promise385  var p2 = Promise.resolve(p1)386  var p3 = Promise.resolve(p2)387  p3.then(388    function(x) { assertAsync(x === 5, "then/resolve") },389    assertUnreachable390  )391  deferred.resolve(5)392  assertAsyncRan()393})();394(function() {395  var deferred = Promise.defer()396  var p1 = deferred.promise397  var p2 = Promise.accept(p1)398  var p3 = Promise.accept(p2)399  p3.chain(400    assertUnreachable,401    function(x) { assertAsync(x === 5, "chain/reject") }402  )403  deferred.reject(5)404  assertAsyncRan()405})();406(function() {407  var deferred = Promise.defer()408  var p1 = deferred.promise409  var p2 = Promise.accept(p1)410  var p3 = Promise.accept(p2)411  p3.then(412    assertUnreachable,413    function(x) { assertAsync(x === 5, "then/reject") }414  )415  deferred.reject(5)416  assertAsyncRan()417})();418(function() {419  var deferred = Promise.defer()420  var p1 = deferred.promise421  var p2 = p1.then(1, 2)422  p2.then(423    function(x) { assertAsync(x === 5, "then/resolve-non-function") },424    assertUnreachable425  )426  deferred.resolve(5)427  assertAsyncRan()428})();429(function() {430  var deferred = Promise.defer()431  var p1 = deferred.promise432  var p2 = p1.then(1, 2)433  p2.then(434    assertUnreachable,435    function(x) { assertAsync(x === 5, "then/reject-non-function") }436  )437  deferred.reject(5)438  assertAsyncRan()439})();440(function() {441  var deferred = Promise.defer()442  var p1 = deferred.promise443  var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}444  var p3 = Promise.accept(p2)445  p3.chain(446    function(x) { assertAsync(x === 5, "chain/resolve/thenable") },447    assertUnreachable448  )449  deferred.resolve(5)450  assertAsyncRan()451})();452(function() {453  var deferred = Promise.defer()454  var p1 = deferred.promise455  var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}456  var p3 = Promise.accept(p2)457  p3.then(458    function(x) { assertAsync(x === 5, "then/resolve/thenable") },459    assertUnreachable460  )461  deferred.resolve(5)462  assertAsyncRan()463})();464(function() {465  var deferred = Promise.defer()466  var p1 = deferred.promise467  var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}468  var p3 = Promise.accept(p2)469  p3.chain(470    assertUnreachable,471    function(x) { assertAsync(x === 5, "chain/reject/thenable") }472  )473  deferred.reject(5)474  assertAsyncRan()475})();476(function() {477  var deferred = Promise.defer()478  var p1 = deferred.promise479  var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}480  var p3 = Promise.accept(p2)481  p3.then(482    assertUnreachable,483    function(x) { assertAsync(x === 5, "then/reject/thenable") }484  )485  deferred.reject(5)486  assertAsyncRan()487})();488(function() {489  var p1 = Promise.accept(5)490  var p2 = Promise.accept(p1)491  var deferred = Promise.defer()492  var p3 = deferred.promise493  p3.chain(494    function(x) { assertAsync(x === 5, "chain/resolve2") },495    assertUnreachable496  )497  deferred.resolve(p2)498  assertAsyncRan()499})();500(function() {501  var p1 = Promise.accept(5)502  var p2 = Promise.accept(p1)503  var deferred = Promise.defer()504  var p3 = deferred.promise505  p3.then(506    function(x) { assertAsync(x === 5, "then/resolve2") },507    assertUnreachable508  )509  deferred.resolve(p2)510  assertAsyncRan()511})();512(function() {513  var p1 = Promise.accept(5)514  var p2 = Promise.accept(p1)515  var deferred = Promise.defer()516  var p3 = deferred.promise517  p3.chain(518    assertUnreachable,519    function(x) { assertAsync(x === 5, "chain/reject2") }520  )521  deferred.reject(5)522  assertAsyncRan()523})();524(function() {525  var p1 = Promise.accept(5)526  var p2 = Promise.accept(p1)527  var deferred = Promise.defer()528  var p3 = deferred.promise529  p3.then(530    assertUnreachable,531    function(x) { assertAsync(x === 5, "then/reject2") }532  )533  deferred.reject(5)534  assertAsyncRan()535})();536(function() {537  var p1 = Promise.accept(5)538  var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}539  var deferred = Promise.defer()540  var p3 = deferred.promise541  p3.chain(542    function(x) { assertAsync(x === 5, "chain/resolve/thenable2") },543    assertUnreachable544  )545  deferred.resolve(p2)546  assertAsyncRan()547})();548(function() {549  var p1 = Promise.accept(5)550  var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}551  var deferred = Promise.defer()552  var p3 = deferred.promise553  p3.then(554    function(x) { assertAsync(x === 5, "then/resolve/thenable2") },555    assertUnreachable556  )557  deferred.resolve(p2)558  assertAsyncRan()559})();560(function() {561  var p1 = Promise.accept(0)562  var p2 = p1.chain(function(x) { return p2 }, assertUnreachable)563  p2.chain(564    assertUnreachable,565    function(r) { assertAsync(r instanceof TypeError, "cyclic/chain") }566  )567  assertAsyncRan()568})();569(function() {570  var p1 = Promise.accept(0)571  var p2 = p1.then(function(x) { return p2 }, assertUnreachable)572  p2.chain(573    assertUnreachable,574    function(r) { assertAsync(r instanceof TypeError, "cyclic/then") }575  )576  assertAsyncRan()577})();578(function() {579  var deferred = Promise.defer()580  var p = deferred.promise581  deferred.resolve(p)582  p.chain(583    assertUnreachable,584    function(r) { assertAsync(r instanceof TypeError, "cyclic/deferred/then") }585  )586  assertAsyncRan()587})();588(function() {589  var deferred = Promise.defer()590  var p = deferred.promise591  deferred.resolve(p)592  p.then(593    assertUnreachable,594    function(r) { assertAsync(r instanceof TypeError, "cyclic/deferred/then") }595  )596  assertAsyncRan()597})();598(function() {599  Promise.all([]).chain(600    function(x) { assertAsync(x.length === 0, "all/resolve/empty") },601    assertUnreachable602  )603  assertAsyncRan()604})();605(function() {606  function testPromiseAllNonIterable(value) {607    Promise.all(value).chain(608        assertUnreachable,609        function(r) {610          assertAsync(r instanceof TypeError, 'all/non iterable');611        });612    assertAsyncRan();613  }614  testPromiseAllNonIterable(null);615  testPromiseAllNonIterable(undefined);616  testPromiseAllNonIterable({});617  testPromiseAllNonIterable(42);618})();619(function() {620  var deferred = Promise.defer();621  var p = deferred.promise;622  function* f() {623    yield 1;624    yield p;625    yield 3;626  }627  Promise.all(f()).chain(628      function(x) {629        assertAsync(x.length === 3, "all/resolve/iterable");630        assertAsync(x[0] === 1, "all/resolve/iterable/0");631        assertAsync(x[1] === 2, "all/resolve/iterable/1");632        assertAsync(x[2] === 3, "all/resolve/iterable/2");633      },634      assertUnreachable);635  deferred.resolve(2);636  assertAsyncRan();637  assertAsyncRan();638  assertAsyncRan();639  assertAsyncRan();640})();641(function() {642  var deferred1 = Promise.defer()643  var p1 = deferred1.promise644  var deferred2 = Promise.defer()645  var p2 = deferred2.promise646  var deferred3 = Promise.defer()647  var p3 = deferred3.promise648  Promise.all([p1, p2, p3]).chain(649    function(x) {650      assertAsync(x.length === 3, "all/resolve")651      assertAsync(x[0] === 1, "all/resolve/0")652      assertAsync(x[1] === 2, "all/resolve/1")653      assertAsync(x[2] === 3, "all/resolve/2")654    },655    assertUnreachable656  )657  deferred1.resolve(1)658  deferred3.resolve(3)659  deferred2.resolve(2)660  assertAsyncRan()661  assertAsyncRan()662  assertAsyncRan()663  assertAsyncRan()664})();665(function() {666  var deferred = Promise.defer()667  var p1 = deferred.promise668  var p2 = Promise.accept(2)669  var p3 = Promise.defer().promise670  Promise.all([p1, p2, p3]).chain(671    assertUnreachable,672    assertUnreachable673  )674  deferred.resolve(1)675})();676(function() {677  var deferred1 = Promise.defer()678  var p1 = deferred1.promise679  var deferred2 = Promise.defer()680  var p2 = deferred2.promise681  var deferred3 = Promise.defer()682  var p3 = deferred3.promise683  Promise.all([p1, p2, p3]).chain(684    assertUnreachable,685    function(x) { assertAsync(x === 2, "all/reject") }686  )687  deferred1.resolve(1)688  deferred3.resolve(3)689  deferred2.reject(2)690  assertAsyncRan()691})();692(function() {693  'use strict';694  var getCalls = 0;695  var funcCalls = 0;696  var nextCalls = 0;697  defineProperty(numberPrototype, symbolIterator, {698    get: function() {699      assertEquals('number', typeof this);700      getCalls++;701      return function() {702        assertEquals('number', typeof this);703        funcCalls++;704        var n = this;705        var i = 0706        return {707          next() {708            nextCalls++;709            return {value: i++, done: i > n};710          }711        };712      };713    },714    configurable: true715  });716  Promise.all(3).chain(717      function(x) {718        assertAsync(x.length === 3, "all/iterable/number/length");719        assertAsync(x[0] === 0, "all/iterable/number/0");720        assertAsync(x[1] === 1, "all/iterable/number/1");721        assertAsync(x[2] === 2, "all/iterable/number/2");722      },723      assertUnreachable);724  delete numberPrototype[symbolIterator];725  assertEquals(getCalls, 1);726  assertEquals(funcCalls, 1);727  assertEquals(nextCalls, 3 + 1);  // + 1 for {done: true}728  assertAsyncRan();729  assertAsyncRan();730  assertAsyncRan();731  assertAsyncRan();732})();733(function() {734  Promise.race([]).chain(735    assertUnreachable,736    assertUnreachable737  )738})();739(function() {740  var p1 = Promise.accept(1)741  var p2 = Promise.accept(2)742  var p3 = Promise.accept(3)743  Promise.race([p1, p2, p3]).chain(744    function(x) { assertAsync(x === 1, "resolved/one") },745    assertUnreachable746  )747  assertAsyncRan()748})();749(function() {750  var p1 = Promise.accept(1)751  var p2 = Promise.accept(2)752  var p3 = Promise.accept(3)753  Promise.race([0, p1, p2, p3]).chain(754    function(x) { assertAsync(x === 0, "resolved-const/one") },755    assertUnreachable756  )757  assertAsyncRan()758})();759(function() {760  var deferred1 = Promise.defer()761  var p1 = deferred1.promise762  var deferred2 = Promise.defer()763  var p2 = deferred2.promise764  var deferred3 = Promise.defer()765  var p3 = deferred3.promise766  Promise.race([p1, p2, p3]).chain(767    function(x) { assertAsync(x === 3, "one/resolve") },768    assertUnreachable769  )770  deferred3.resolve(3)771  deferred1.resolve(1)772  assertAsyncRan()773})();774(function() {775  var deferred = Promise.defer()776  var p1 = deferred.promise777  var p2 = Promise.accept(2)778  var p3 = Promise.defer().promise779  Promise.race([p1, p2, p3]).chain(780    function(x) { assertAsync(x === 2, "resolved/one") },781    assertUnreachable782  )783  deferred.resolve(1)784  assertAsyncRan()785})();786(function() {787  var deferred1 = Promise.defer()788  var p1 = deferred1.promise789  var deferred2 = Promise.defer()790  var p2 = deferred2.promise791  var deferred3 = Promise.defer()792  var p3 = deferred3.promise793  Promise.race([p1, p2, p3]).chain(794    function(x) { assertAsync(x === 3, "one/resolve/reject") },795    assertUnreachable796  )797  deferred3.resolve(3)798  deferred1.reject(1)799  assertAsyncRan()800})();801(function() {802  var deferred1 = Promise.defer()803  var p1 = deferred1.promise804  var deferred2 = Promise.defer()805  var p2 = deferred2.promise806  var deferred3 = Promise.defer()807  var p3 = deferred3.promise808  Promise.race([p1, p2, p3]).chain(809    assertUnreachable,810    function(x) { assertAsync(x === 3, "one/reject/resolve") }811  )812  deferred3.reject(3)813  deferred1.resolve(1)814  assertAsyncRan()815})();816(function() {817  function testPromiseRaceNonIterable(value) {818    Promise.race(value).chain(819        assertUnreachable,820        function(r) {821          assertAsync(r instanceof TypeError, 'race/non iterable');822        });823    assertAsyncRan();824  }825  testPromiseRaceNonIterable(null);826  testPromiseRaceNonIterable(undefined);827  testPromiseRaceNonIterable({});828  testPromiseRaceNonIterable(42);829})();830(function() {831  var deferred1 = Promise.defer()832  var p1 = deferred1.promise833  var deferred2 = Promise.defer()834  var p2 = deferred2.promise835  var deferred3 = Promise.defer()836  var p3 = deferred3.promise837  function* f() {838    yield p1;839    yield p2;840    yield p3;841  }842  Promise.race(f()).chain(843    function(x) { assertAsync(x === 3, "race/iterable/resolve/reject") },844    assertUnreachable845  )846  deferred3.resolve(3)847  deferred1.reject(1)848  assertAsyncRan()849})();850(function() {851  var deferred1 = Promise.defer()852  var p1 = deferred1.promise853  var deferred2 = Promise.defer()854  var p2 = deferred2.promise855  var deferred3 = Promise.defer()856  var p3 = deferred3.promise857  function* f() {858    yield p1;859    yield p2;860    yield p3;861  }862  Promise.race(f()).chain(863    assertUnreachable,864    function(x) { assertAsync(x === 3, "race/iterable/reject/resolve") }865  )866  deferred3.reject(3)867  deferred1.resolve(1)868  assertAsyncRan()869})();870(function() {871  'use strict';872  var getCalls = 0;873  var funcCalls = 0;874  var nextCalls = 0;875  defineProperty(numberPrototype, symbolIterator, {876    get: function() {877      assertEquals('number', typeof this);878      getCalls++;879      return function() {880        assertEquals('number', typeof this);881        funcCalls++;882        var n = this;883        var i = 0884        return {885          next() {886            nextCalls++;887            return {value: i++, done: i > n};888          }889        };890      };891    },892    configurable: true893  });894  Promise.race(3).chain(895      function(x) {896        assertAsync(x === 0, "race/iterable/number");897      },898      assertUnreachable);899  delete numberPrototype[symbolIterator];900  assertEquals(getCalls, 1);901  assertEquals(funcCalls, 1);902  assertEquals(nextCalls, 3 + 1);  // + 1 for {done: true}903  assertAsyncRan();904})();905(function() {906  var log907  function MyPromise(resolver) {908    log += "n"909    var promise = new Promise(function(resolve, reject) {910      resolver(911        function(x) { log += "x" + x; resolve(x) },912        function(r) { log += "r" + r; reject(r) }913      )914    })915    promise.__proto__ = MyPromise.prototype916    return promise917  }918  MyPromise.__proto__ = Promise919  MyPromise.defer = function() {920    log += "d"921    return call(this.__proto__.defer, this)922  }923  MyPromise.prototype.__proto__ = Promise.prototype924  MyPromise.prototype.chain = function(resolve, reject) {925    log += "c"926    return call(this.__proto__.__proto__.chain, this, resolve, reject)927  }928  log = ""929  var p1 = new MyPromise(function(resolve, reject) { resolve(1) })930  var p2 = new MyPromise(function(resolve, reject) { reject(2) })931  var d3 = MyPromise.defer()932  assertTrue(d3.promise instanceof Promise, "subclass/instance")933  assertTrue(d3.promise instanceof MyPromise, "subclass/instance-my3")934  assertTrue(log === "nx1nr2dn", "subclass/create")935  log = ""936  var p4 = MyPromise.resolve(4)937  var p5 = MyPromise.reject(5)938  assertTrue(p4 instanceof MyPromise, "subclass/instance4")939  assertTrue(p4 instanceof MyPromise, "subclass/instance-my4")940  assertTrue(p5 instanceof MyPromise, "subclass/instance5")941  assertTrue(p5 instanceof MyPromise, "subclass/instance-my5")942  d3.resolve(3)943  assertTrue(log === "nx4nr5x3", "subclass/resolve")944  log = ""945  var d6 = MyPromise.defer()946  d6.promise.chain(function(x) {947    return new Promise(function(resolve) { resolve(x) })948  }).chain(function() {})949  d6.resolve(6)950  assertTrue(log === "dncncnx6", "subclass/chain")951  log = ""952  Promise.all([11, Promise.accept(12), 13, MyPromise.accept(14), 15, 16])953  assertTrue(log === "nx14", "subclass/all/arg")954  log = ""955  MyPromise.all([21, Promise.accept(22), 23, MyPromise.accept(24), 25, 26])956  assertTrue(log === "nx24nnx21nnx[object Promise]nnx23nnnx25nnx26n",957             "subclass/all/self")958})();959(function() {960  'use strict';961  class Pact extends Promise { }962  class Vow  extends Pact    { }963  class Oath extends Vow     { }964  Oath.constructor = Vow;965  assertTrue(Pact.resolve(Pact.resolve()).constructor === Pact,966             "subclass/resolve/own");967  assertTrue(Pact.resolve(Promise.resolve()).constructor === Pact,968             "subclass/resolve/ancestor");969  assertTrue(Pact.resolve(Vow.resolve()).constructor === Pact,970             "subclass/resolve/descendant"); var vow = Vow.resolve();971  vow.constructor = Oath;972  assertTrue(Oath.resolve(vow) === vow,973             "subclass/resolve/descendant with transplanted own constructor");974}());975(function() {976  var thenCalled = false;977  var resolve;978  var promise = new Promise(function(res) { resolve = res; });979  resolve({ then() { thenCalled = true; throw new Error(); } });980  assertLater(function() { return thenCalled; }, "resolve-with-thenable");981});982(function() {983  var calledWith;984  var resolve;985  var p1 = (new Promise(function(res) { resolve = res; }));986  var p2 = p1.then(function(v) {987    return {988      then(resolve, reject) { resolve({ then() { calledWith = v }}); }989    };990  });991  resolve({ then(resolve) { resolve(2); } });992  assertLater(function() { return calledWith === 2; },993              "resolve-with-thenable2");994})();995(function() {996  var p = Promise.resolve();997  var callCount = 0;998  defineProperty(p, "constructor", {999    get: function() { ++callCount; return Promise; }...Deferred.js
Source:Deferred.js  
1/*2 Ext.Deferred adapted from:3 [DeftJS](https://github.com/deftjs/deftjs5)4 Copyright (c) 2012-2013 [DeftJS Framework Contributors](http://deftjs.org)5 Open source under the [MIT License](http://en.wikipedia.org/wiki/MIT_License).6 when(), all(), any(), some(), map(), reduce(), delay() and timeout()7 sequence(), parallel(), pipeline()8 methods adapted from: [when.js](https://github.com/cujojs/when)9 Copyright (c) B Cavalier & J Hann10 Open source under the [MIT License](http://en.wikipedia.org/wiki/MIT_License).11 */12/**13 * Deferreds are the mechanism used to create new Promises. A Deferred has a single14 * associated Promise that can be safely returned to external consumers to ensure they do15 * not interfere with the resolution or rejection of the deferred operation.16 *17 * This implementation of Promises is an extension of the ECMAScript 6 Promises API as18 * detailed [here][1]. For a compatible, though less full featured, API see `{@link Ext.Promise}`.19 *20 * A Deferred is typically used within the body of a function that performs an asynchronous21 * operation. When that operation succeeds, the Deferred should be resolved; if that22 * operation fails, the Deferred should be rejected.23 *24 * Each Deferred has an associated Promise. A Promise delegates `then` calls to its25 * Deferred's `then` method. In this way, access to Deferred operations are divided between26 * producer (Deferred) and consumer (Promise) roles.27 *28 * ## Basic Usage29 *30 * In it's most common form, a method will create and return a Promise like this:31 *32 *      // A method in a service class which uses a Store and returns a Promise33 *      //34 *      loadCompanies: function () {35 *          var deferred = new Ext.Deferred(); // create the Ext.Deferred object36 *37 *          this.companyStore.load({38 *              callback: function (records, operation, success) {39 *                  if (success) {40 *                      // Use "deferred" to drive the promise:41 *                      deferred.resolve(records);42 *                  }43 *                  else {44 *                      // Use "deferred" to drive the promise:45 *                      deferred.reject("Error loading Companies.");46 *                  }47 *              }48 *          });49 *50 *          return deferred.promise;  // return the Promise to the caller51 *      }52 *53 * You can see this method first creates a `{@link Ext.Deferred Deferred}` object. It then54 * returns its `Promise` object for use by the caller. Finally, in the asynchronous55 * callback, it resolves the `deferred` object if the call was successful, and rejects the56 * `deferred` if the call failed.57 *58 * When a Deferred's `resolve` method is called, it fulfills with the optionally specified59 * value. If `resolve` is called with a then-able (i.e.a Function or Object with a `then`60 * function, such as another Promise) it assimilates the then-able's result; the Deferred61 * provides its own `resolve` and `reject` methods as the onFulfilled or onRejected62 * arguments in a call to that then-able's `then` function. If an error is thrown while63 * calling the then-able's `then` function (prior to any call back to the specified64 * `resolve` or `reject` methods), the Deferred rejects with that error. If a Deferred's65 * `resolve` method is called with its own Promise, it rejects with a TypeError.66 *67 * When a Deferred's `reject` method is called, it rejects with the optionally specified68 * reason.69 *70 * Each time a Deferred's `then` method is called, it captures a pair of optional71 * onFulfilled and onRejected callbacks and returns a Promise of the Deferred's future72 * value as transformed by those callbacks.73 *74 * See `{@link Ext.promise.Promise}` for an example of using the returned Promise.75 *76 * @since 6.0.077 */78Ext.define('Ext.Deferred', function (Deferred) {79    var ExtPromise,80        when;81return {82    extend: 'Ext.promise.Deferred',83    requires: [84        'Ext.Promise'85    ],86    statics: {87        _ready: function () {88            // Our requires are met, so we can cache Ext.promise.Deferred89            ExtPromise = Ext.promise.Promise;90            when = Ext.Promise.resolve;91        },92        /**93         * Returns a new Promise that will only resolve once all the specified94         * `promisesOrValues` have resolved.95         *96         * The resolution value will be an Array containing the resolution value of each97         * of the `promisesOrValues`.98         *99         * @param {Mixed[]/Ext.promise.Promise[]/Ext.promise.Promise} promisesOrValues An100         * Array of values or Promises, or a Promise of an Array of values or Promises.101         * @return {Ext.promise.Promise} A Promise of an Array of the resolved values.102         * @static103         */104        all: function () {105            return ExtPromise.all.apply(ExtPromise, arguments);106        },107        /**108         * Initiates a competitive race, returning a new Promise that will resolve when109         * any one of the specified `promisesOrValues` have resolved, or will reject when110         * all `promisesOrValues` have rejected or cancelled.111         *112         * The resolution value will the first value of `promisesOrValues` to resolve.113         *114         * @param {Mixed[]/Ext.promise.Promise[]/Ext.promise.Promise} promisesOrValues An115         * Array of values or Promises, or a Promise of an Array of values or Promises.116         * @return {Ext.promise.Promise} A Promise of the first resolved value.117         * @static118         */119        any: function (promisesOrValues) {120            //<debug>121            if (!(Ext.isArray(promisesOrValues) || ExtPromise.is(promisesOrValues))) {122                Ext.raise('Invalid parameter: expected an Array or Promise of an Array.');123            }124            //</debug>125            return Deferred.some(promisesOrValues, 1).then(function (array) {126                return array[0];127            }, function (error) {128                if (error instanceof Error &&129                    error.message === 'Too few Promises were resolved.') {130                    Ext.raise('No Promises were resolved.');131                }132                else {133                    throw error;134                }135            });136        },137        /**138         * Returns a new Promise that will automatically resolve with the specified139         * Promise or value after the specified delay (in milliseconds).140         *141         * @param {Mixed} promiseOrValue A Promise or value.142         * @param {Number} milliseconds A delay duration (in milliseconds).143         * @return {Ext.promise.Promise} A Promise of the specified Promise or value that144         * will resolve after the specified delay.145         * @static146         */147        delay: function (promiseOrValue, milliseconds) {148            var deferred;149            if (arguments.length === 1) {150                milliseconds = promiseOrValue;151                promiseOrValue = undefined;152            }153            milliseconds = Math.max(milliseconds, 0);154            deferred = new Deferred();155            setTimeout(function () {156                deferred.resolve(promiseOrValue);157            }, milliseconds);158            return deferred.promise;159        },160        /**161         * Traditional map function, similar to `Array.prototype.map()`, that allows162         * input to contain promises and/or values.163         *164         * The specified map function may return either a value or a promise.165         *166         * @param {Mixed[]/Ext.promise.Promise[]/Ext.promise.Promise} promisesOrValues An167         * Array of values or Promises, or a Promise of an Array of values or Promises.168         * @param {Function} mapFn A Function to call to transform each resolved value in169         * the Array.170         * @return {Ext.promise.Promise} A Promise of an Array of the mapped resolved171         * values.172         * @static173         */174        map: function (promisesOrValues, mapFn) {175            //<debug>176            if (!(Ext.isArray(promisesOrValues) || ExtPromise.is(promisesOrValues))) {177                Ext.raise('Invalid parameter: expected an Array or Promise of an Array.');178            }179            if (!Ext.isFunction(mapFn)) {180                Ext.raise('Invalid parameter: expected a function.');181            }182            //</debug>183            return Deferred.resolved(promisesOrValues).then(function (promisesOrValues) {184                var deferred, index, promiseOrValue, remainingToResolve, resolve, results, i, len;185                remainingToResolve = promisesOrValues.length;186                results = new Array(promisesOrValues.length);187                deferred = new Deferred();188                if (!remainingToResolve) {189                    deferred.resolve(results);190                }191                else {192                    resolve = function (item, index) {193                        return Deferred.resolved(item).then(function (value) {194                            return mapFn(value, index, results);195                        }).then(function (value) {196                            results[index] = value;197                            if (!--remainingToResolve) {198                                deferred.resolve(results);199                            }200                            return value;201                        }, function (reason) {202                            return deferred.reject(reason);203                        });204                    };205                    for (index = i = 0, len = promisesOrValues.length; i < len; index = ++i) {206                        promiseOrValue = promisesOrValues[index];207                        if (index in promisesOrValues) {208                            resolve(promiseOrValue, index);209                        }210                        else {211                            remainingToResolve--;212                        }213                    }214                }215                return deferred.promise;216            });217        },218        /**219         * Returns a new function that wraps the specified function and caches the220         * results for previously processed inputs.221         *222         * Similar to {@link Ext.Function#memoize Ext.Function.memoize()}, except it223         * allows for parameters that are Promises and/or values.224         *225         * @param {Function} fn A Function to wrap.226         * @param {Object} scope An optional scope in which to execute the wrapped function.227         * @param {Function} hashFn An optional function used to compute a hash key for228         * storing the result, based on the arguments to the original function.229         * @return {Function} The new wrapper function.230         * @static231         */232        memoize: function (fn, scope, hashFn) {233            var memoizedFn = Ext.Function.memoize(fn, scope, hashFn);234            return function () {235                return Deferred.all(Ext.Array.slice(arguments)).then(function (values) {236                    return memoizedFn.apply(scope, values);237                });238            };239        },240        /**241         * Execute an Array (or {@link Ext.promise.Promise Promise} of an Array) of242         * functions in parallel.243         *244         * The specified functions may optionally return their results as245         * {@link Ext.promise.Promise Promises}.246         *247         * @param {Function[]/Ext.promise.Promise} fns The Array (or Promise of an Array)248         * of functions to execute.249         * @param {Object} scope Optional scope in which to execute the specified functions.250         * @return {Ext.promise.Promise} Promise of an Array of results for each function251         * call (in the same order).252         * @static253         */254        parallel: function (fns, scope) {255            if (scope == null) {256                scope = null;257            }258            var args = Ext.Array.slice(arguments, 2);259            return Deferred.map(fns, function (fn) {260                if (!Ext.isFunction(fn)) {261                    throw new Error('Invalid parameter: expected a function.');262                }263                return fn.apply(scope, args);264            });265        },266        /**267         * Execute an Array (or {@link Ext.promise.Promise Promise} of an Array) of268         * functions as a pipeline, where each function's result is passed to the269         * subsequent function as input.270         *271         * The specified functions may optionally return their results as272         * {@link Ext.promise.Promise Promises}.273         *274         * @param {Function[]/Ext.promise.Promise} fns The Array (or Promise of an Array)275         * of functions to execute.276         * @param {Object} initialValue Initial value to be passed to the first function277         * in the pipeline.278         * @param {Object} scope Optional scope in which to execute the specified functions.279         * @return {Ext.promise.Promise} Promise of the result value for the final280         * function in the pipeline.281         * @static282         */283        pipeline: function (fns, initialValue, scope) {284            if (scope == null) {285                scope = null;286            }287            return Deferred.reduce(fns, function (value, fn) {288                if (!Ext.isFunction(fn)) {289                    throw new Error('Invalid parameter: expected a function.');290                }291                return fn.call(scope, value);292            }, initialValue);293        },294        /**295         * Traditional reduce function, similar to `Array.reduce()`, that allows input to296         * contain promises and/or values.297         *298         * @param {Mixed[]/Ext.promise.Promise[]/Ext.promise.Promise} values An299         * Array of values or Promises, or a Promise of an Array of values or Promises.300         * @param {Function} reduceFn A Function to call to transform each successive301         * item in the Array into the final reduced value.302         * @param {Mixed} initialValue An initial Promise or value.303         * @return {Ext.promise.Promise} A Promise of the reduced value.304         * @static305         */306        reduce: function (values, reduceFn, initialValue) {307            //<debug>308            if (!(Ext.isArray(values) || ExtPromise.is(values))) {309                Ext.raise('Invalid parameter: expected an Array or Promise of an Array.');310            }311            if (!Ext.isFunction(reduceFn)) {312                Ext.raise('Invalid parameter: expected a function.');313            }314            //</debug>315            var initialValueSpecified = arguments.length === 3;316            return Deferred.resolved(values).then(function (promisesOrValues) {317                var reduceArguments = [318                    promisesOrValues,319                    function (previousValueOrPromise, currentValueOrPromise, currentIndex) {320                        return Deferred.resolved(previousValueOrPromise).then(function (previousValue) {321                            return Deferred.resolved(currentValueOrPromise).then(function (currentValue) {322                                return reduceFn(previousValue, currentValue, currentIndex, promisesOrValues);323                            });324                        });325                    }326                ];327                if (initialValueSpecified) {328                    reduceArguments.push(initialValue);329                }330                return Ext.Array.reduce.apply(Ext.Array, reduceArguments);331            });332        },333        /**334         * Convenience method that returns a new Promise rejected with the specified335         * reason.336         *337         * @param {Error} reason Rejection reason.338         * @return {Ext.promise.Promise} The rejected Promise.339         * @static340         */341        rejected: function (reason) {342            var deferred = new Ext.Deferred();343            deferred.reject(reason);344            return deferred.promise;345        },346        /**347         * Returns a new Promise that either348         *349         *  * Resolves immediately for the specified value, or350         *  * Resolves or rejects when the specified promise (or third-party Promise or351         *    then()-able) is resolved or rejected.352         *353         * @param {Mixed} promiseOrValue A Promise (or third-party Promise or then()-able)354         * or value.355         * @return {Ext.promise.Promise} A Promise of the specified Promise or value.356         * @static357         */358        resolved: function (value) {359            var deferred = new Ext.Deferred();360            deferred.resolve(value);361            return deferred.promise;362        },363        /**364         * Execute an Array (or {@link Ext.promise.Promise Promise} of an Array) of365         * functions sequentially.366         *367         * The specified functions may optionally return their results as {@link368         * Ext.promise.Promise Promises}.369         *370         * @param {Function[]/Ext.promise.Promise} fns The Array (or Promise of an Array)371         * of functions to execute.372         * @param {Object} scope Optional scope in which to execute the specified functions.373         * @return {Ext.promise.Promise} Promise of an Array of results for each function374         * call (in the same order).375         * @static376         */377        sequence: function (fns, scope) {378            if (scope == null) {379                scope = null;380            }381            var args = Ext.Array.slice(arguments, 2);382            return Deferred.reduce(fns, function (results, fn) {383                if (!Ext.isFunction(fn)) {384                    throw new Error('Invalid parameter: expected a function.');385                }386                return Deferred.resolved(fn.apply(scope, args)).then(function (result) {387                    results.push(result);388                    return results;389                });390            }, []);391        },392        /**393         * Initiates a competitive race, returning a new Promise that will resolve when394         * `howMany` of the specified `promisesOrValues` have resolved, or will reject395         * when it becomes impossible for `howMany` to resolve.396         *397         * The resolution value will be an Array of the first `howMany` values of398         * `promisesOrValues` to resolve.399         *400         * @param {Mixed[]/Ext.promise.Promise[]/Ext.promise.Promise} promisesOrValues An401         * Array of values or Promises, or a Promise of an Array of values or Promises.402         * @param {Number} howMany The expected number of resolved values.403         * @return {Ext.promise.Promise} A Promise of the expected number of resolved404         * values.405         * @static406         */407        some: function (promisesOrValues, howMany) {408            //<debug>409            if (!(Ext.isArray(promisesOrValues) || ExtPromise.is(promisesOrValues))) {410                Ext.raise('Invalid parameter: expected an Array or Promise of an Array.');411            }412            if (!Ext.isNumeric(howMany) || howMany <= 0) {413                Ext.raise('Invalid parameter: expected a positive integer.');414            }415            //</debug>416            return Deferred.resolved(promisesOrValues).then(function (promisesOrValues) {417                var deferred, index, onReject, onResolve, promiseOrValue,418                    remainingToReject, remainingToResolve, values, i, len;419                values = [];420                remainingToResolve = howMany;421                remainingToReject = (promisesOrValues.length - remainingToResolve) + 1;422                deferred = new Deferred();423                if (promisesOrValues.length < howMany) {424                    deferred.reject(new Error('Too few Promises were resolved.'));425                }426                else {427                    onResolve = function (value) {428                        if (remainingToResolve > 0) {429                            values.push(value);430                        }431                        remainingToResolve--;432                        if (remainingToResolve === 0) {433                            deferred.resolve(values);434                        }435                        return value;436                    };437                    onReject = function (reason) {438                        remainingToReject--;439                        if (remainingToReject === 0) {440                            deferred.reject(new Error('Too few Promises were resolved.'));441                        }442                        return reason;443                    };444                    for (index = i = 0, len = promisesOrValues.length; i < len; index = ++i) {445                        promiseOrValue = promisesOrValues[index];446                        if (index in promisesOrValues) {447                            Deferred.resolved(promiseOrValue).then(onResolve, onReject);448                        }449                    }450                }451                return deferred.promise;452            });453        },454        /**455         * Returns a new Promise that will automatically reject after the specified456         * timeout (in milliseconds) if the specified promise has not resolved or457         * rejected.458         *459         * @param {Mixed} promiseOrValue A Promise or value.460         * @param {Number} milliseconds A timeout duration (in milliseconds).461         * @return {Ext.promise.Promise} A Promise of the specified Promise or value that462         * enforces the specified timeout.463         * @static464         */465        timeout: function (promiseOrValue, milliseconds) {466            var deferred = new Deferred(),467                timeoutId;468            timeoutId = setTimeout(function () {469                if (timeoutId) {470                    deferred.reject(new Error('Promise timed out.'));471                }472            }, milliseconds);473            Deferred.resolved(promiseOrValue).then(function (value) {474                clearTimeout(timeoutId);475                timeoutId = null;476                deferred.resolve(value);477            }, function (reason) {478                clearTimeout(timeoutId);479                timeoutId = null;480                deferred.reject(reason);481            });482            return deferred.promise;483        }484    }485}},486function (Deferred) {487    Deferred._ready();...when.js
Source:when.js  
...65			// It's a when.js promise, so we trust it66			promise = promiseOrValue;67		} else {68			// It's not a when.js promise. See if it's a foreign promise or a value.69			if(isPromise(promiseOrValue)) {70				// It's a thenable, but we don't know where it came from, so don't trust71				// its implementation entirely.  Introduce a trusted middleman when.js promise72				deferred = defer();73				// IMPORTANT: This is the only place when.js should ever call .then() on an74				// untrusted promise. Don't expose the return value to the untrusted promise75				promiseOrValue.then(76					function(value)  { deferred.resolve(value); },77					function(reason) { deferred.reject(reason); },78					function(update) { deferred.progress(update); }79				);80				promise = deferred.promise;81			} else {82				// It's a value, not a promise.  Create a resolved promise for it.83				promise = fulfilled(promiseOrValue);84			}85		}86		return promise;87	}88	/**89	 * Returns a rejected promise for the supplied promiseOrValue.  The returned90	 * promise will be rejected with:91	 * - promiseOrValue, if it is a value, or92	 * - if promiseOrValue is a promise93	 *   - promiseOrValue's value after it is fulfilled94	 *   - promiseOrValue's reason after it is rejected95	 * @param {*} promiseOrValue the rejected value of the returned {@link Promise}96	 * @returns {Promise} rejected {@link Promise}97	 */98	function reject(promiseOrValue) {99		return when(promiseOrValue, rejected);100	}101	/**102	 * Trusted Promise constructor.  A Promise created from this constructor is103	 * a trusted when.js promise.  Any other duck-typed promise is considered104	 * untrusted.105	 * @constructor106	 * @name Promise107	 */108	function Promise(then) {109		this.then = then;110	}111	Promise.prototype = {112		/**113		 * Register a callback that will be called when a promise is114		 * fulfilled or rejected.  Optionally also register a progress handler.115		 * Shortcut for .then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress)116		 * @param {function?} [onFulfilledOrRejected]117		 * @param {function?} [onProgress]118		 * @returns {Promise}119		 */120		always: function(onFulfilledOrRejected, onProgress) {121			return this.then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress);122		},123		/**124		 * Register a rejection handler.  Shortcut for .then(undefined, onRejected)125		 * @param {function?} onRejected126		 * @returns {Promise}127		 */128		otherwise: function(onRejected) {129			return this.then(undef, onRejected);130		},131		/**132		 * Shortcut for .then(function() { return value; })133		 * @param  {*} value134		 * @returns {Promise} a promise that:135		 *  - is fulfilled if value is not a promise, or136		 *  - if value is a promise, will fulfill with its value, or reject137		 *    with its reason.138		 */139		yield: function(value) {140			return this.then(function() {141				return value;142			});143		},144		/**145		 * Assumes that this promise will fulfill with an array, and arranges146		 * for the onFulfilled to be called with the array as its argument list147		 * i.e. onFulfilled.spread(undefined, array).148		 * @param {function} onFulfilled function to receive spread arguments149		 * @returns {Promise}150		 */151		spread: function(onFulfilled) {152			return this.then(function(array) {153				// array may contain promises, so resolve its contents.154				return all(array, function(array) {155					return onFulfilled.apply(undef, array);156				});157			});158		}159	};160	/**161	 * Create an already-resolved promise for the supplied value162	 * @private163	 *164	 * @param {*} value165	 * @returns {Promise} fulfilled promise166	 */167	function fulfilled(value) {168		var p = new Promise(function(onFulfilled) {169			// TODO: Promises/A+ check typeof onFulfilled170			try {171				return resolve(onFulfilled ? onFulfilled(value) : value);172			} catch(e) {173				return rejected(e);174			}175		});176		return p;177	}178	/**179	 * Create an already-rejected {@link Promise} with the supplied180	 * rejection reason.181	 * @private182	 *183	 * @param {*} reason184	 * @returns {Promise} rejected promise185	 */186	function rejected(reason) {187		var p = new Promise(function(_, onRejected) {188			// TODO: Promises/A+ check typeof onRejected189			try {190				return onRejected ? resolve(onRejected(reason)) : rejected(reason);191			} catch(e) {192				return rejected(e);193			}194		});195		return p;196	}197	/**198	 * Creates a new, Deferred with fully isolated resolver and promise parts,199	 * either or both of which may be given out safely to consumers.200	 * The Deferred itself has the full API: resolve, reject, progress, and201	 * then. The resolver has resolve, reject, and progress.  The promise202	 * only has then.203	 *204	 * @returns {Deferred}205	 */206	function defer() {207		var deferred, promise, handlers, progressHandlers,208			_then, _progress, _resolve;209		/**210		 * The promise for the new deferred211		 * @type {Promise}212		 */213		promise = new Promise(then);214		/**215		 * The full Deferred object, with {@link Promise} and {@link Resolver} parts216		 * @class Deferred217		 * @name Deferred218		 */219		deferred = {220			then:     then, // DEPRECATED: use deferred.promise.then221			resolve:  promiseResolve,222			reject:   promiseReject,223			// TODO: Consider renaming progress() to notify()224			progress: promiseProgress,225			promise:  promise,226			resolver: {227				resolve:  promiseResolve,228				reject:   promiseReject,229				progress: promiseProgress230			}231		};232		handlers = [];233		progressHandlers = [];234		/**235		 * Pre-resolution then() that adds the supplied callback, errback, and progback236		 * functions to the registered listeners237		 * @private238		 *239		 * @param {function?} [onFulfilled] resolution handler240		 * @param {function?} [onRejected] rejection handler241		 * @param {function?} [onProgress] progress handler242		 */243		_then = function(onFulfilled, onRejected, onProgress) {244			// TODO: Promises/A+ check typeof onFulfilled, onRejected, onProgress245			var deferred, progressHandler;246			deferred = defer();247			progressHandler = typeof onProgress === 'function'248				? function(update) {249					try {250						// Allow progress handler to transform progress event251						deferred.progress(onProgress(update));252					} catch(e) {253						// Use caught value as progress254						deferred.progress(e);255					}256				}257				: function(update) { deferred.progress(update); };258			handlers.push(function(promise) {259				promise.then(onFulfilled, onRejected)260					.then(deferred.resolve, deferred.reject, progressHandler);261			});262			progressHandlers.push(progressHandler);263			return deferred.promise;264		};265		/**266		 * Issue a progress event, notifying all progress listeners267		 * @private268		 * @param {*} update progress event payload to pass to all listeners269		 */270		_progress = function(update) {271			processQueue(progressHandlers, update);272			return update;273		};274		/**275		 * Transition from pre-resolution state to post-resolution state, notifying276		 * all listeners of the resolution or rejection277		 * @private278		 * @param {*} value the value of this deferred279		 */280		_resolve = function(value) {281			value = resolve(value);282			// Replace _then with one that directly notifies with the result.283			_then = value.then;284			// Replace _resolve so that this Deferred can only be resolved once285			_resolve = resolve;286			// Make _progress a noop, to disallow progress for the resolved promise.287			_progress = noop;288			// Notify handlers289			processQueue(handlers, value);290			// Free progressHandlers array since we'll never issue progress events291			progressHandlers = handlers = undef;292			return value;293		};294		return deferred;295		/**296		 * Wrapper to allow _then to be replaced safely297		 * @param {function?} [onFulfilled] resolution handler298		 * @param {function?} [onRejected] rejection handler299		 * @param {function?} [onProgress] progress handler300		 * @returns {Promise} new promise301		 */302		function then(onFulfilled, onRejected, onProgress) {303			// TODO: Promises/A+ check typeof onFulfilled, onRejected, onProgress304			return _then(onFulfilled, onRejected, onProgress);305		}306		/**307		 * Wrapper to allow _resolve to be replaced308		 */309		function promiseResolve(val) {310			return _resolve(val);311		}312		/**313		 * Wrapper to allow _reject to be replaced314		 */315		function promiseReject(err) {316			return _resolve(rejected(err));317		}318		/**319		 * Wrapper to allow _progress to be replaced320		 */321		function promiseProgress(update) {322			return _progress(update);323		}324	}325	/**326	 * Determines if promiseOrValue is a promise or not.  Uses the feature327	 * test from http://wiki.commonjs.org/wiki/Promises/A to determine if328	 * promiseOrValue is a promise.329	 *330	 * @param {*} promiseOrValue anything331	 * @returns {boolean} true if promiseOrValue is a {@link Promise}332	 */333	function isPromise(promiseOrValue) {334		return promiseOrValue && typeof promiseOrValue.then === 'function';335	}336	/**337	 * Initiates a competitive race, returning a promise that will resolve when338	 * howMany of the supplied promisesOrValues have resolved, or will reject when339	 * it becomes impossible for howMany to resolve, for example, when340	 * (promisesOrValues.length - howMany) + 1 input promises reject.341	 *342	 * @param {Array} promisesOrValues array of anything, may contain a mix343	 *      of promises and values344	 * @param howMany {number} number of promisesOrValues to resolve345	 * @param {function?} [onFulfilled] resolution handler346	 * @param {function?} [onRejected] rejection handler347	 * @param {function?} [onProgress] progress handler...promise.js
Source:promise.js  
...42  // Promise Resolve Functions43  var resolve = value => {44    if (alreadyResolved === true) return;45    alreadyResolved = true;46    ResolvePromise(promise, value);47  };48  // ES#sec-promise-reject-functions49  // Promise Reject Functions50  var reject = reason => {51    if (alreadyResolved === true) return;52    alreadyResolved = true;53    RejectPromise(promise, reason);54  };55  return {56    __proto__: null,57    resolve: resolve,58    reject: reject59  };60}61// ES#sec-promise-executor62// Promise ( executor )63var GlobalPromise = function Promise(executor) {64  if (executor === promiseRawSymbol) {65    return %_NewObject(GlobalPromise, new.target);66  }67  if (IS_UNDEFINED(new.target)) throw MakeTypeError(kNotAPromise, this);68  if (!IS_CALLABLE(executor)) {69    throw MakeTypeError(kResolverNotAFunction, executor);70  }71  var promise = PromiseInit(%_NewObject(GlobalPromise, new.target));72  var callbacks = CreateResolvingFunctions(promise);73  var debug_is_active = DEBUG_IS_ACTIVE;74  try {75    if (debug_is_active) %DebugPushPromise(promise, Promise);76    executor(callbacks.resolve, callbacks.reject);77  } catch (e) {78    %_Call(callbacks.reject, UNDEFINED, e);79  } finally {80    if (debug_is_active) %DebugPopPromise();81  }82  return promise;83}84// Core functionality.85function PromiseSet(promise, status, value) {86  SET_PRIVATE(promise, promiseStateSymbol, status);87  SET_PRIVATE(promise, promiseResultSymbol, value);88  // There are 3 possible states for the resolve, reject symbols when we add89  // a new callback --90  // 1) UNDEFINED -- This is the zero state where there is no callback91  // registered. When we see this state, we directly attach the callbacks to92  // the symbol.93  // 2) !IS_ARRAY -- There is a single callback directly attached to the94  // symbols. We need to create a new array to store additional callbacks.95  // 3) IS_ARRAY -- There are multiple callbacks already registered,96  // therefore we can just push the new callback to the existing array.97  SET_PRIVATE(promise, promiseFulfillReactionsSymbol, UNDEFINED);98  SET_PRIVATE(promise, promiseRejectReactionsSymbol, UNDEFINED);99  // There are 2 possible states for this symbol --100  // 1) UNDEFINED -- This is the zero state, no deferred object is101  // attached to this symbol. When we want to add a new deferred we102  // directly attach it to this symbol.103  // 2) symbol with attached deferred object -- New deferred objects104  // are not attached to this symbol, but instead they are directly105  // attached to the resolve, reject callback arrays. At this point,106  // the deferred symbol's state is stale, and the deferreds should be107  // read from the reject, resolve callbacks.108  SET_PRIVATE(promise, promiseDeferredReactionsSymbol, UNDEFINED);109  return promise;110}111function PromiseCreateAndSet(status, value) {112  var promise = new GlobalPromise(promiseRawSymbol);113  // If debug is active, notify about the newly created promise first.114  if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED);115  return PromiseSet(promise, status, value);116}117function PromiseInit(promise) {118  return PromiseSet(promise, kPending, UNDEFINED);119}120function FulfillPromise(promise, status, value, promiseQueue) {121  if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) {122    var tasks = GET_PRIVATE(promise, promiseQueue);123    if (!IS_UNDEFINED(tasks)) {124      var tasks = GET_PRIVATE(promise, promiseQueue);125      var deferreds = GET_PRIVATE(promise, promiseDeferredReactionsSymbol);126      PromiseEnqueue(value, tasks, deferreds, status);127    }128    PromiseSet(promise, status, value);129  }130}131function PromiseHandle(value, handler, deferred) {132  var debug_is_active = DEBUG_IS_ACTIVE;133  try {134    if (debug_is_active) %DebugPushPromise(deferred.promise, PromiseHandle);135    var result = handler(value);136    deferred.resolve(result);137  } catch (exception) {138    try { deferred.reject(exception); } catch (e) { }139  } finally {140    if (debug_is_active) %DebugPopPromise();141  }142}143function PromiseEnqueue(value, tasks, deferreds, status) {144  var id, name, instrumenting = DEBUG_IS_ACTIVE;145  %EnqueueMicrotask(function() {146    if (instrumenting) {147      %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });148    }149    if (IS_ARRAY(tasks)) {150      for (var i = 0; i < tasks.length; i += 2) {151        PromiseHandle(value, tasks[i], tasks[i + 1]);152      }153    } else {154      PromiseHandle(value, tasks, deferreds);155    }156    if (instrumenting) {157      %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });158    }159  });160  if (instrumenting) {161    id = ++lastMicrotaskId;162    name = status === kFulfilled ? "Promise.resolve" : "Promise.reject";163    %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });164  }165}166function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) {167  var maybeResolveCallbacks =168      GET_PRIVATE(promise, promiseFulfillReactionsSymbol);169  if (IS_UNDEFINED(maybeResolveCallbacks)) {170    SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve);171    SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject);172    SET_PRIVATE(promise, promiseDeferredReactionsSymbol, deferred);173  } else if (!IS_ARRAY(maybeResolveCallbacks)) {174    var resolveCallbacks = new InternalArray();175    var rejectCallbacks = new InternalArray();176    var existingDeferred = GET_PRIVATE(promise, promiseDeferredReactionsSymbol);177    resolveCallbacks.push(178        maybeResolveCallbacks, existingDeferred, onResolve, deferred);179    rejectCallbacks.push(GET_PRIVATE(promise, promiseRejectReactionsSymbol),180                         existingDeferred,181                         onReject,182                         deferred);183    SET_PRIVATE(promise, promiseFulfillReactionsSymbol, resolveCallbacks);184    SET_PRIVATE(promise, promiseRejectReactionsSymbol, rejectCallbacks);185  } else {186    maybeResolveCallbacks.push(onResolve, deferred);187    GET_PRIVATE(promise, promiseRejectReactionsSymbol).push(onReject, deferred);188  }189}190function PromiseIdResolveHandler(x) { return x }191function PromiseIdRejectHandler(r) { throw r }192function PromiseNopResolver() {}193// -------------------------------------------------------------------194// Define exported functions.195// For bootstrapper.196// ES#sec-ispromise IsPromise ( x )197function IsPromise(x) {198  return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStateSymbol);199}200function PromiseCreate() {201  return new GlobalPromise(PromiseNopResolver)202}203// ES#sec-promise-resolve-functions204// Promise Resolve Functions, steps 6-13205function ResolvePromise(promise, resolution) {206  if (resolution === promise) {207    return RejectPromise(promise, MakeTypeError(kPromiseCyclic, resolution));208  }209  if (IS_RECEIVER(resolution)) {210    // 25.4.1.3.2 steps 8-12211    try {212      var then = resolution.then;213    } catch (e) {214      return RejectPromise(promise, e);215    }216    // Resolution is a native promise and if it's already resolved or217    // rejected, shortcircuit the resolution procedure by directly218    // reusing the value from the promise.219    if (IsPromise(resolution) && then === PromiseThen) {220      var thenableState = GET_PRIVATE(resolution, promiseStateSymbol);221      if (thenableState === kFulfilled) {222        // This goes inside the if-else to save one symbol lookup in223        // the slow path.224        var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol);225        FulfillPromise(promise, kFulfilled, thenableValue,226                       promiseFulfillReactionsSymbol);227        SET_PRIVATE(promise, promiseHasHandlerSymbol, true);228        return;229      } else if (thenableState === kRejected) {230        var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol);231        if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) {232          // Promise has already been rejected, but had no handler.233          // Revoke previously triggered reject event.234          %PromiseRevokeReject(resolution);235        }236        RejectPromise(promise, thenableValue);237        SET_PRIVATE(resolution, promiseHasHandlerSymbol, true);238        return;239      }240    }241    if (IS_CALLABLE(then)) {242      // PromiseResolveThenableJob243      var id;244      var name = "PromiseResolveThenableJob";245      var instrumenting = DEBUG_IS_ACTIVE;246      %EnqueueMicrotask(function() {247        if (instrumenting) {248          %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });249        }250        var callbacks = CreateResolvingFunctions(promise);251        try {252          %_Call(then, resolution, callbacks.resolve, callbacks.reject);253        } catch (e) {254          %_Call(callbacks.reject, UNDEFINED, e);255        }256        if (instrumenting) {257          %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });258        }259      });260      if (instrumenting) {261        id = ++lastMicrotaskId;262        %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });263      }264      return;265    }266  }267  FulfillPromise(promise, kFulfilled, resolution, promiseFulfillReactionsSymbol);268}269// ES#sec-rejectpromise270// RejectPromise ( promise, reason )271function RejectPromise(promise, reason) {272  // Check promise status to confirm that this reject has an effect.273  // Call runtime for callbacks to the debugger or for unhandled reject.274  if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) {275    var debug_is_active = DEBUG_IS_ACTIVE;276    if (debug_is_active ||277        !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) {278      %PromiseRejectEvent(promise, reason, debug_is_active);279    }280  }281  FulfillPromise(promise, kRejected, reason, promiseRejectReactionsSymbol)282}283// ES#sec-newpromisecapability284// NewPromiseCapability ( C )285function NewPromiseCapability(C) {286  if (C === GlobalPromise) {287    // Optimized case, avoid extra closure.288    var promise = PromiseInit(new GlobalPromise(promiseRawSymbol));289    var callbacks = CreateResolvingFunctions(promise);290    return {291      promise: promise,292      resolve: callbacks.resolve,293      reject: callbacks.reject294    };295  }296  var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED };297  result.promise = new C((resolve, reject) => {298    if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject))299        throw MakeTypeError(kPromiseExecutorAlreadyInvoked);300    result.resolve = resolve;301    result.reject = reject;302  });303  if (!IS_CALLABLE(result.resolve) || !IS_CALLABLE(result.reject))304      throw MakeTypeError(kPromiseNonCallable);305  return result;306}307// Unspecified V8-specific legacy function308function PromiseDefer() {309  %IncrementUseCounter(kPromiseDefer);310  return NewPromiseCapability(this);311}312// Unspecified V8-specific legacy function313function PromiseAccept(x) {314  %IncrementUseCounter(kPromiseAccept);315  return %_Call(PromiseResolve, this, x);316}317// ES#sec-promise.reject318// Promise.reject ( x )319function PromiseReject(r) {320  if (!IS_RECEIVER(this)) {321    throw MakeTypeError(kCalledOnNonObject, PromiseResolve);322  }323  if (this === GlobalPromise) {324    // Optimized case, avoid extra closure.325    var promise = PromiseCreateAndSet(kRejected, r);326    // The debug event for this would always be an uncaught promise reject,327    // which is usually simply noise. Do not trigger that debug event.328    %PromiseRejectEvent(promise, r, false);329    return promise;330  } else {331    var promiseCapability = NewPromiseCapability(this);332    %_Call(promiseCapability.reject, UNDEFINED, r);333    return promiseCapability.promise;334  }335}336// Shortcut Promise.reject and Promise.resolve() implementations, used by337// Async Functions implementation.338function PromiseCreateRejected(r) {339  return %_Call(PromiseReject, GlobalPromise, r);340}341function PromiseCreateResolved(x) {342  return %_Call(PromiseResolve, GlobalPromise, x);343}344// ES#sec-promise.prototype.then345// Promise.prototype.then ( onFulfilled, onRejected )346// Multi-unwrapped chaining with thenable coercion.347function PromiseThen(onResolve, onReject) {348  var status = GET_PRIVATE(this, promiseStateSymbol);349  if (IS_UNDEFINED(status)) {350    throw MakeTypeError(kNotAPromise, this);351  }352  var constructor = SpeciesConstructor(this, GlobalPromise);353  onResolve = IS_CALLABLE(onResolve) ? onResolve : PromiseIdResolveHandler;354  onReject = IS_CALLABLE(onReject) ? onReject : PromiseIdRejectHandler;355  var deferred = NewPromiseCapability(constructor);356  switch (status) {357    case kPending:358      PromiseAttachCallbacks(this, deferred, onResolve, onReject);359      break;360    case kFulfilled:361      PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),362                     onResolve, deferred, kFulfilled);363      break;364    case kRejected:365      if (!HAS_DEFINED_PRIVATE(this, promiseHasHandlerSymbol)) {366        // Promise has already been rejected, but had no handler.367        // Revoke previously triggered reject event.368        %PromiseRevokeReject(this);369      }370      PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),371                     onReject, deferred, kRejected);372      break;373  }374  // Mark this promise as having handler.375  SET_PRIVATE(this, promiseHasHandlerSymbol, true);376  return deferred.promise;377}378// Unspecified V8-specific legacy function379// Chain is left around for now as an alias for then380function PromiseChain(onResolve, onReject) {381  %IncrementUseCounter(kPromiseChain);382  return %_Call(PromiseThen, this, onResolve, onReject);383}384// ES#sec-promise.prototype.catch385// Promise.prototype.catch ( onRejected )386function PromiseCatch(onReject) {387  return this.then(UNDEFINED, onReject);388}389// Combinators.390// ES#sec-promise.resolve391// Promise.resolve ( x )392function PromiseResolve(x) {393  if (!IS_RECEIVER(this)) {394    throw MakeTypeError(kCalledOnNonObject, PromiseResolve);395  }396  if (IsPromise(x) && x.constructor === this) return x;397  var promiseCapability = NewPromiseCapability(this);398  var resolveResult = %_Call(promiseCapability.resolve, UNDEFINED, x);399  return promiseCapability.promise;400}401// ES#sec-promise.all402// Promise.all ( iterable )403function PromiseAll(iterable) {404  if (!IS_RECEIVER(this)) {405    throw MakeTypeError(kCalledOnNonObject, "Promise.all");406  }407  var deferred = NewPromiseCapability(this);408  var resolutions = new InternalArray();409  var count;410  function CreateResolveElementFunction(index, values, promiseCapability) {...知乎大佬自己写的promise.js
Source:知乎大佬自己写的promise.js  
...7 * 1. æ¯å¦æ¯å¯¹è±¡å¹¶ä¸ä¸æ¯ null8 * 2. æ¯å¦æ then 屿§å¹¶ä¸ then æ¯ä¸ä¸ªæ¹æ³9 * @param {*} val 10 */11function isPromise(val) {12  if (typeof val === 'object' && val !== null || typeof val === 'function') {13    return typeof val.then === 'function';14  }15  return false;16}17console.log('--------------------- MY Promise ---------------------');18// å®ç°é¾å¼è°ç¨19/**20 * å¤ç then ä¸çæåã失败åè°å½æ°è¿å弿¯å¦æ¯ Promise çæ
åµ21 * @param {*} promise2 åè§ Promise A+ è§è说æ new Promise22 * @param {*} x æ¯æåã失败åè°çè¿åå¼23 */24const resolvePromise = (promise2, x) => {25  const { resolve, reject } = promise2;26  // è¿éç夿æ¯å¯è½èªå·±ç Promise è¦åå«äººç Promise æ··ç¨ï¼å¯è½ä¸åç Promise åºä¹é´ç¸äºè°ç¨27  // 妿 new åºæ¥ç Promise2 å x æ¯åä¸ä¸ªï¼é£ä¹ x æ°¸è¿ä¸è½æåæè
å¤±è´¥ï¼æä»¥å¡æ»äºï¼ç´æ¥æ¥é28  if (promise2 === x) return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));29  // éè¦å¤æ x çç¶æï¼å¤æ x æ¯ä¸æ¯ Promise30  // å
夿æ¯ä¸æ¯å¯¹è±¡æè
彿°31  if (typeof x === 'object' && x !== null || typeof x === 'function') {32    let called; // è¿éèèå«äººç Promise æ¯å¦å¥å£®ï¼ä¸å¥å£®éè¦å夿ä¸ä¸ï¼è°ç¨äºæåå°±ä¸è½å¤±è´¥ï¼è°ç¨ç失败就ä¸è½æåãä¸è½å¤æ¬¡è°ç¨æåæè
失败33    try {34      const then = x.then; // å
é¨å¯è½æåºé误35      // 妿 then 䏿¯å½æ°å°±è¯´ææ¯ä¸ä¸ªæ®éå¼ï¼ç´æ¥è¿å x 36      if (typeof then !== 'function') resolve(x); // æ¯å¦ï¼{ then: 'mhq' }37      else {38        // è¿éä¸è¦å次è°ç¨ x.then æ¯é²æ¢å then çæ¶åæ¥éï¼ä¸ä¸ then æ¹æ³é颿åºäºä¸ä¸ªé误å¢ï¼39        then.call(x, y => {40          if (called) return;41          called = true;42          // 妿 x æ¯ä¸ä¸ª Promiseï¼é£ä¹å°±ç»§ç»è§£ææåçå¼43          resolvePromise(promise2, y);44        }, f => {45          if (called) return;46          called = true;47          reject(f); // ç´æ¥è°ç¨ r ä½ä¸ºå¤±è´¥çç»æ48        });49      }50    } catch (err) {51      if (called) return;52      called = true;53      reject(err);54    }55  } else {56    resolve(x);57  }58};59class Promise {60  constructor(executor) {61    // Promise çç¶æ62    this.status = PENDING;63    // æååçå¼64    this.value = undefined;65    // 失败åçå¼66    this.reason = undefined;67    // æååè°å½æ°ï¼åå¸è®¢é
68    this.onResolvedCallbacks = [];69    // 失败åè°å½æ°ï¼åå¸è®¢é
70    this.onRejectedCallbacks = [];71    /**72     * Promise å
鍿ä¾ç resolveï¼è®© Promise çç¶æåææåæï¼å¹¶è®©æååè°æ§è¡73     * @param {*} value 74     */75    const resolve = value => {76      if (value instanceof Promise) {77        return value.then(resolve, reject);78      }79      if (this.status === PENDING) {80        this.status = FULFILLED;81        this.value = value;82        this.onResolvedCallbacks.forEach(fn => fn());83      }84    };85    /**86     * Promise å
鍿ä¾ç rejectï¼è®© Promise çç¶æåæå¤±è´¥æï¼å¹¶è®©å¤±è´¥åè°æ§è¡87     * @param {*} reason 88     */89    const reject = reason => {90      if (this.status === PENDING) {91        this.status = REJECTED;92        this.reason = reason;93        this.onRejectedCallbacks.forEach(fn => fn());94      }95    };96    // try + catch åªè½æè·åæ¥å¼å¸¸97    try {98      executor(resolve, reject);99    } catch (err) {100      reject(err);101    }102  }103  // åªè¦ x æ¯ä¸ä¸ªæ®éå¼ï¼å°±ä¼è®©ä¸ä¸ª Promise åææåæ104  // è¿ä¸ª x æå¯è½æ¯ä¸ä¸ª Promiseï¼éè¦èå个è¿ä¸ª Promise çç¶æ105  then(onFulfilled, onRejected) {106    // æ¯å¦.then().then().then(() => {}); è¿ç§è°ç¨ï¼å¯¹å¯éåæ°çå¤çï¼éä¼ 107    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;108    onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };109    const promise2 = new Promise((resolve, reject) => { // 䏿¦ new åç«å³æ§è¡110      if (this.status === FULFILLED) {111        setTimeout(() => {112          promise2.resolve = resolve;113          promise2.reject = reject;114          try {115            const x = onFulfilled(this.value);116            resolvePromise(promise2, x);117          } catch (err) {118            reject(err);119          }120        }, 0);121      }122      if (this.status === REJECTED) {123        setTimeout(() => {124          promise2.resolve = resolve;125          promise2.reject = reject;126          try {127            const x = onRejected(this.reason);128            resolvePromise(promise2, x);129          } catch (err) {130            reject(err);131          }132        }, 0);133      }134      if (this.status === PENDING) { // æ¬èº«æ¯å¼æ¥ç135        this.onResolvedCallbacks.push(() => {136          setTimeout(() => { // è¿ééè¦å ä¸ï¼ä¸å ä¸è·æµè¯è·ä¸é137            promise2.resolve = resolve;138            promise2.reject = reject;139            try {140              const x = onFulfilled(this.value);141              resolvePromise(promise2, x);142            } catch (err) {143              reject(err);144            }145          });146        });147        this.onRejectedCallbacks.push(() => {148          setTimeout(() => {149            promise2.resolve = resolve;150            promise2.reject = reject;151            try {152              const x = onRejected(this.reason);153              resolvePromise(promise2, x);154            } catch (err) {155              reject(err);156            }157          });158        });159      }160    });161    return promise2;162  }163  /**164   * Promise ä¸ç catch æä»£çå°±æ¯ then 没ææååè°çä¸ä¸ªå«åèå·²165   * @param {*} errCallback 166   */167  catch(errCallback) {168    return this.then(null, errCallback);169  }170}171// æ è®ºå¦ä½é½ä¼æ§è¡ï¼æä¸ä¸ä¸ª then çç»æåä¸ä¼ éï¼å¦æ finally ä¸è¿åäºä¸ä¸ª Promise ä¼çå¾
è¿ä¸ª Promise æ§è¡å®æåç»§ç»æ§è¡172Promise.prototype.finally = function (callback) {173  return this.then(val => {174    return Promise.resolve(callback()).then(() => val);175  }, (err) => {176    return Promise.resolve(callback()).then(() => {177      throw err;178    });179  });180};181// npm install promises-aplus-tests -g182// promises-aplus-tests promise.js183// æµè¯èªå·±åç Promise æ¯å¦ç¬¦åè§èçå
184Promise.deferred = () => {185  const dfd = {};186  dfd.promise = new Promise((resolve, reject) => {187    dfd.resolve = resolve;188    dfd.reject = reject;189  });190  return dfd;191};192/**193 * Promise.resolve ä»ä¼çå¾
éé¢ç Promise æ§è¡æå194 * @param {*} val 195 */196Promise.resolve = val => {197  return new Promise((resolve) => {198    resolve(val);199  });200};201/**202 * Promise.reject ä¸ä¼çå¾
åæ°ä¸ç Promise æ§è¡å®æ¯203 */204Promise.reject = () => {205  return new Promise((_, reject) => {206    reject(val);207  });208};209/**210 * Promise.all æ¹æ³è¡¨ç¤ºçå¾
ææç Promise å
¨é¨æååæä¼æ§è¡åè°ï¼å¦ææä¸ä¸ª Promise 失败å Promise 就失败äº211 * @param {*} promises 212 */213Promise.all = promises => {214  return new Promise((resolve, reject) => {215    const res = [];216    let count = 0;217    const resolveRes = (index, data) => {218      res[index] = data;219      if (++count === promises.length) {220        resolve(res);221      }222    };223    for (let i = 0; i < promises.length; i++) {224      const current = promises[i];225      if (isPromise(current)) {226        current.then((data) => {227          resolveRes(i, data);228        }, (err) => {229          reject(err);230        });231      } else {232        resolveRes(i, current);233      }234    }235  });236}237/**238 * Promise.race èµè·ï¼è°æ¯ç¬¬ä¸ä¸ªå®æçï¼å°±ç¨ä»çç»æï¼å¦ææ¯å¤±è´¥è¿ä¸ª Promise 就失败ï¼å¦æç¬¬ä¸ä¸ªæ¯æåå°±æ¯æå239 * @param {*} promises 240 */241Promise.race = (promises) => {242  return new Promise((resolve, reject) => {243    for (let i = 0; i < promises.length; i++) {244      let current = promises[i];245      if (isPromise(current)) {246        current.then(resolve, reject);247      } else {248        resolve(current);249        break;250      }251    }252  });253}254// ä¸é¨ç» node ç api åç promisify æ¹æ³ï¼å¦ fs.readFile255Promise.promisify = fn => {256  return (...arg) => {257    return new Promise((resolve, reject) => {258      fn(...arg, (err, data) => {259        if (err) reject(err);260        resolve(data);261      });262    });263  }264};265module.exports = Promise;266var p = {267  then: (resolve, reject) => {268      setTimeout(() => {269          resolve(1)270      }, 1000);271  }272}273var p1 = new Promise(274  (resolve, reject) => {275      resolve(p)276  }277)278p1.then((res) => {279  console.log(res);...index.js
Source:index.js  
1/* 2.3 The Promise Resolution Procedure */2function resolvePromise(promise, x) {3    try {4        // 2.3.1 If promise and x refer to the same object, reject promise with a TypeError as the reason.5        if (promise === x) {6            throw new TypeError('promise cannot be resolved with itself.');7        }8        // 2.3.2 If x is promise9        // 2.3.3 If x is an object or function10        if (11            x &&12            (typeof x === 'object' || typeof x === 'function')13        ) {14            var then = x.then;15            // 2.3.3.3 If then is a function, call it with x as this, first argument resolvePromise, and second argument rejectPromise16            if (typeof then === 'function') {17                startResolve(promise, function (resolve, reject) {18                    then.call(x, resolve, reject);19                });20                return;21            }22        }23        // 2.3.3.4 If then is not a function, fulfill promise with x.24        // 2.3.4 If x is not an object or function, fulfill promise with x.25        doResolve(promise, x);26    } catch (e) {27        // 2.3.3.2 If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason28        // 2.3.3.3.4.2 If calling then throws an exception e, reject promise with e as the reason.29        doReject(promise, e);30    }31}32function doResolve(promise, value) {33    promise._state = 'resolved';34    promise._value = value;35    _handleDeferreds(promise);36}37function doReject(promise, reason) {38    promise._state = 'rejected';39    promise._value = reason;40    _handleDeferreds(promise);41}42function startResolve(promise, fn) {43    var called = false;44    if (typeof fn !== 'function') {45        throw new Error('Promise procedure must be a function.');46    }47    try {48        fn(49            function (value) {50                // 2.2.2.3 onFulfilled must not be called more than once.51                if (called) return;52                if (promise._state === 'pending') {53                    called = true;54                    resolvePromise(promise, value);55                }56            },57            function (reason) {58                // 2.2.3.3 onRejected must not be called more than once.59                if (called) return;60                if (promise._state === 'pending') {61                    called = true;62                    doReject(promise, reason);63                }64            }65        );66    } catch (e) {67        // 2.3.3.3.4.1 If resolvePromise or rejectPromise have been called, ignore it.68        if (called) return;69        if (promise._state === 'pending') {70            called = true;71            doReject(promise, e);72        }73    }74}75function Promise(fn) {76    if (typeof fn !== 'function') {77        throw new Error('Promise resolver is not a function');78    }79    this._state = 'pending';80    this._value = null;81    this._deferreds = [];82    startResolve(this, fn);83}84/*85* 2.2.6 Then may be called multiple times on the same promise.86* All respective callbacks must execute in the order of their originating calls to then.87*/88function _handleDeferreds(promise) {89    // 2.2.4 onFulfilled or onRejected must not be called until the execution context stack contains only platform code.90    setTimeout(function () {91        var deferreds = promise._deferreds;92        var state = promise._state;93        while (deferreds.length) {94            var defer = deferreds.shift();95            try {96                resolvePromise(97                    defer.promise,98                    defer[state === 'resolved' ? 'onFulfilled' : 'onRejected'](promise._value)99                );100            } catch (e) {101                doReject(defer.promise, e);102            }103        }104    }, 0);105}106function _handleThen(promise, onFulfilled, onRejected) {107    var promise2;108    if (promise._state === 'pending') {109        promise2 = new Promise(function () {});110        promise._deferreds.push({111            onFulfilled: onFulfilled,112            onRejected: onRejected,113            promise: promise2114        });115    } else {116        promise2 = new Promise(function (resolve, reject) {117            setTimeout(function () {118                try {119                    // 2.2.7.1 If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).120                    var fn = promise._state === 'resolved' ? onFulfilled : onRejected;121                    resolve(fn(promise._value));122                } catch (e) {123                    // 2.2.7.2 If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason.124                    reject(e);125                }126            }, 0);127        });128    }129    return promise2;130}131Promise.prototype.then = function (onFulfilled, onRejected) {132    // 2.2.7.3 If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value as promise1.133    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function (value) {134        return value;135    };136    // 2.2.7.4 If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason as promise1.137    onRejected = typeof onRejected === 'function' ? onRejected : function (reason) {138        throw reason;139    };140    return _handleThen(this, onFulfilled, onRejected);141};142Promise.prototype.catch = function (onRejected) {143    return this.then(null, onRejected);144};145Promise.prototype.finally = function (fn) {146    return this.then(147        function (value) {148            return fn(value);149        },150        function (reason) {151            return fn(reason);152        }153    );154};155Promise.resolve = function (value) {156    return new Promise(function (resolve) {157        resolve(value);158    });159};160Promise.reject = function (reason) {161    return new Promise(function (resolve, reject) {162        reject(reason);163    });164};165Promise.all = function (defers) {166    if (!Array.isArray(defers)) {167        throw 'Promise.all only accepts Array.';168    }169    var results = [].concat(defers);170    var remain = defers.length;171    return new Promise(function (resolve, reject) {172        if (remain === 0) {173            resolve([]);174            return;175        }176        var getRes = function (x, i) {177            try {178                if (179                    x &&180                    (typeof x === 'object' || typeof x === 'function')181                ) {182                    var then = x.then;183                    if (typeof then === 'function') {184                        then.call(x, function (value) {185                            getRes(value, i);186                        }, reject);187                        return;188                    }189                }190                results[i] = x;191                if (--remain === 0) {192                    resolve(results);193                }194            } catch (e) {195                reject(e);196            }197        }198        defers.forEach(function (defer, idx) {199            getRes(defer, idx);200        });201    });202};203Promise.race = function (defers) {204    if (!Array.isArray(defers)) {205        throw 'Promise.race only accepts Array.';206    }207    return new Promise(function (resolve, reject) {208        var getRes = function (x) {209            try {210                if (211                    x &&212                    (typeof x === 'object' || typeof x === 'function')213                ) {214                    var then = x.then;215                    if (typeof then === 'function') {216                        then.call(x, resolve, reject);217                        return;218                    }219                }220                resolve(x);221            } catch (e) {...eslint-plugin-promise_vx.x.x.js
Source:eslint-plugin-promise_vx.x.x.js  
1// flow-typed signature: cd888a19a61bc75c46972c5f589c09502// flow-typed version: <<STUB>>/eslint-plugin-promise_v^4.1.1/flow_v0.101.03/**4 * This is an autogenerated libdef stub for:5 *6 *   'eslint-plugin-promise'7 *8 * Fill this stub out by replacing all the `any` types.9 *10 * Once filled out, we encourage you to share your work with the11 * community by sending a pull request to:12 * https://github.com/flowtype/flow-typed13 */14declare module 'eslint-plugin-promise' {15  declare module.exports: any;16}17/**18 * We include stubs for each file inside this npm package in case you need to19 * require those files directly. Feel free to delete any files that aren't20 * needed.21 */22declare module 'eslint-plugin-promise/rules/always-return' {23  declare module.exports: any;24}25declare module 'eslint-plugin-promise/rules/avoid-new' {26  declare module.exports: any;27}28declare module 'eslint-plugin-promise/rules/catch-or-return' {29  declare module.exports: any;30}31declare module 'eslint-plugin-promise/rules/lib/get-docs-url' {32  declare module.exports: any;33}34declare module 'eslint-plugin-promise/rules/lib/has-promise-callback' {35  declare module.exports: any;36}37declare module 'eslint-plugin-promise/rules/lib/is-callback' {38  declare module.exports: any;39}40declare module 'eslint-plugin-promise/rules/lib/is-inside-callback' {41  declare module.exports: any;42}43declare module 'eslint-plugin-promise/rules/lib/is-inside-promise' {44  declare module.exports: any;45}46declare module 'eslint-plugin-promise/rules/lib/is-named-callback' {47  declare module.exports: any;48}49declare module 'eslint-plugin-promise/rules/lib/is-promise' {50  declare module.exports: any;51}52declare module 'eslint-plugin-promise/rules/lib/promise-statics' {53  declare module.exports: any;54}55declare module 'eslint-plugin-promise/rules/no-callback-in-promise' {56  declare module.exports: any;57}58declare module 'eslint-plugin-promise/rules/no-native' {59  declare module.exports: any;60}61declare module 'eslint-plugin-promise/rules/no-nesting' {62  declare module.exports: any;63}64declare module 'eslint-plugin-promise/rules/no-new-statics' {65  declare module.exports: any;66}67declare module 'eslint-plugin-promise/rules/no-promise-in-callback' {68  declare module.exports: any;69}70declare module 'eslint-plugin-promise/rules/no-return-in-finally' {71  declare module.exports: any;72}73declare module 'eslint-plugin-promise/rules/no-return-wrap' {74  declare module.exports: any;75}76declare module 'eslint-plugin-promise/rules/param-names' {77  declare module.exports: any;78}79declare module 'eslint-plugin-promise/rules/prefer-await-to-callbacks' {80  declare module.exports: any;81}82declare module 'eslint-plugin-promise/rules/prefer-await-to-then' {83  declare module.exports: any;84}85declare module 'eslint-plugin-promise/rules/valid-params' {86  declare module.exports: any;87}88// Filename aliases89declare module 'eslint-plugin-promise/index' {90  declare module.exports: $Exports<'eslint-plugin-promise'>;91}92declare module 'eslint-plugin-promise/index.js' {93  declare module.exports: $Exports<'eslint-plugin-promise'>;94}95declare module 'eslint-plugin-promise/rules/always-return.js' {96  declare module.exports: $Exports<'eslint-plugin-promise/rules/always-return'>;97}98declare module 'eslint-plugin-promise/rules/avoid-new.js' {99  declare module.exports: $Exports<'eslint-plugin-promise/rules/avoid-new'>;100}101declare module 'eslint-plugin-promise/rules/catch-or-return.js' {102  declare module.exports: $Exports<'eslint-plugin-promise/rules/catch-or-return'>;103}104declare module 'eslint-plugin-promise/rules/lib/get-docs-url.js' {105  declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/get-docs-url'>;106}107declare module 'eslint-plugin-promise/rules/lib/has-promise-callback.js' {108  declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/has-promise-callback'>;109}110declare module 'eslint-plugin-promise/rules/lib/is-callback.js' {111  declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/is-callback'>;112}113declare module 'eslint-plugin-promise/rules/lib/is-inside-callback.js' {114  declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/is-inside-callback'>;115}116declare module 'eslint-plugin-promise/rules/lib/is-inside-promise.js' {117  declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/is-inside-promise'>;118}119declare module 'eslint-plugin-promise/rules/lib/is-named-callback.js' {120  declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/is-named-callback'>;121}122declare module 'eslint-plugin-promise/rules/lib/is-promise.js' {123  declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/is-promise'>;124}125declare module 'eslint-plugin-promise/rules/lib/promise-statics.js' {126  declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/promise-statics'>;127}128declare module 'eslint-plugin-promise/rules/no-callback-in-promise.js' {129  declare module.exports: $Exports<'eslint-plugin-promise/rules/no-callback-in-promise'>;130}131declare module 'eslint-plugin-promise/rules/no-native.js' {132  declare module.exports: $Exports<'eslint-plugin-promise/rules/no-native'>;133}134declare module 'eslint-plugin-promise/rules/no-nesting.js' {135  declare module.exports: $Exports<'eslint-plugin-promise/rules/no-nesting'>;136}137declare module 'eslint-plugin-promise/rules/no-new-statics.js' {138  declare module.exports: $Exports<'eslint-plugin-promise/rules/no-new-statics'>;139}140declare module 'eslint-plugin-promise/rules/no-promise-in-callback.js' {141  declare module.exports: $Exports<'eslint-plugin-promise/rules/no-promise-in-callback'>;142}143declare module 'eslint-plugin-promise/rules/no-return-in-finally.js' {144  declare module.exports: $Exports<'eslint-plugin-promise/rules/no-return-in-finally'>;145}146declare module 'eslint-plugin-promise/rules/no-return-wrap.js' {147  declare module.exports: $Exports<'eslint-plugin-promise/rules/no-return-wrap'>;148}149declare module 'eslint-plugin-promise/rules/param-names.js' {150  declare module.exports: $Exports<'eslint-plugin-promise/rules/param-names'>;151}152declare module 'eslint-plugin-promise/rules/prefer-await-to-callbacks.js' {153  declare module.exports: $Exports<'eslint-plugin-promise/rules/prefer-await-to-callbacks'>;154}155declare module 'eslint-plugin-promise/rules/prefer-await-to-then.js' {156  declare module.exports: $Exports<'eslint-plugin-promise/rules/prefer-await-to-then'>;157}158declare module 'eslint-plugin-promise/rules/valid-params.js' {159  declare module.exports: $Exports<'eslint-plugin-promise/rules/valid-params'>;...Using AI Code Generation
1const cavy = require('cavy-cli');2const path = require('path');3const fs = require('fs');4const { promisify } = require('util');5const exec = promisify(require('child_process').exec);6const reportsFolder = path.resolve(__dirname, 'reports');7if (!fs.existsSync(reportsFolder)) {8  fs.mkdirSync(reportsFolder);9}10exec(`npx cavy run-ios --reporter junit --reporter-options output=${reportsFolder}/test-results.xml`)11  .then(() => {12    console.log('Tests completed successfully');13  })14  .catch((err) => {15    console.log('Tests failed', err);16    process.exit(1);17  });18const cavy = require('cavy-cli');19const path = require('path');20const fs = require('fs');21const reportsFolder = path.resolve(__dirname, 'reports');22if (!fs.existsSync(reportsFolder)) {23  fs.mkdirSync(reportsFolder);24}25try {26  await cavy.runTests({27    reporterOptions: {28      output: `${reportsFolder}/test-results.xml`,29    },30  });31  console.log('Tests completed successfully');32} catch (err) {33  console.log('Tests failed', err);34  process.exit(1);35}36const cavy = require('cavy-cli');37const path = require('path');38const fs = require('fs');39const reportsFolder = path.resolve(__dirname, 'reports');40if (!fs.existsSync(reportsFolder)) {41  fs.mkdirSync(reportsFolder);42}43try {44  await cavy.runTests({45    reporterOptions: {46      output: `${reportsFolder}/test-results.xml`,47    },48      { name: 'cavy-custom-reporter', options: { foo: 'bar' } },49  });50  console.log('Tests completed successfully');51} catch (err) {52  console.log('Tests failed', err);53  process.exit(1);54}Using AI Code Generation
1import { useCavy } from 'cavy';2import { useCavy } from 'cavy/lib/hooks';3import { useCavy } from 'cavy';4import { useCavy } from 'cavy/lib/hooks';5import { useCavy } from 'cavy';6import { useCavy } from 'cavy/lib/hooks';7import { useCavy } from 'cavy';8import { useCavy } from 'cavy/lib/hooks';9import { useCavy } from 'cavy';10import { useCavy } from 'cavy/lib/hooks';11import { useCavy } from 'cavy';12import { useCavy } from 'cavy/lib/hooks';13import { useCavy } from 'cavy';14import { useCavy } from 'cavy/lib/hooks';15import { useCavy } from 'cavy';16import { useCavy } from 'cavy/lib/hooks';17import { useCavy } from 'cavy';18import { useCavy } from 'cavy/lib/hooks';19import { useCavy } from 'cavy';20import { useCavyUsing AI Code Generation
1const cavy = require('cavy-cli');2const generateTestHook = cavy.init(cavy.PureTest);3module.exports = generateTestHook;4import test from './test';5<Button testID={test('login-button')} onPress={this.login} title="Login" />6import test from './test';7const spec = require('./App.spec.js');8const { describe, it, expect } = spec;9describe('Login', () => {10  it('login button', async () => {11    await expect(element(test('login-button'))).toBeVisible();12  });13});14import test from './test';15<Button testID={test('login-button')} onPress={this.login} title="Login" />16import test from './test';17const spec = require('./App.spec.js');18const { describe, it, expect, find } = spec;19import App from './App';20describe('Login', () => {21  it('login button', async () => {22    await expect(find(test('login-button'), App)).toExist();23  });24});Using AI Code Generation
1import { it, describe, beforeEach } from 'cavy';2import { it, describe, beforeEach } from 'cavy/spec';3describe('MyComponent', () => {4  let spec;5  beforeEach(function() {6    spec = this.spec;7  });8  it('should have a button', () => {9    spec.findComponent('button');10  });11});12#### `findComponent(componentKey)`13it('should have a button', () => {14  spec.findComponent('button').simulate('press');15});16#### `findComponentWithRef(componentKey)`17it('should have a button', () => {18  spec.findComponentWithRef('button').simulate('press');19});20#### `findComponentWithTestId(componentKey)`21it('should have a button', () => {22  spec.findComponentWithTestId('button').simulate('press');23});24#### `findComponentWithLabel(componentKey)`25it('should have a button', () => {26  spec.findComponentWithLabel('button').simulate('press');27});28#### `findComponentWithHint(componentKey)`29it('should have a button', () => {Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
