| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- /*! Native Promise Only
- v0.8.1 (c) Kyle Simpson
- MIT License: http://getify.mit-license.org
- */
- (function UMD(name,context,definition){
- // special form of UMD for polyfilling across evironments
- context[name] = context[name] || definition();
- if (typeof module != "undefined" && module.exports) { module.exports = context[name]; }
- else if (typeof define == "function" && define.amd) { define(function $AMD$(){ return context[name]; }); }
- })("Promise",typeof global != "undefined" ? global : this,function DEF(){
- /*jshint validthis:true */
- "use strict";
- var builtInProp, cycle, scheduling_queue,
- ToString = Object.prototype.toString,
- timer = (typeof setImmediate != "undefined") ?
- function timer(fn) { return setImmediate(fn); } :
- setTimeout
- ;
- // dammit, IE8.
- try {
- Object.defineProperty({},"x",{});
- builtInProp = function builtInProp(obj,name,val,config) {
- return Object.defineProperty(obj,name,{
- value: val,
- writable: true,
- configurable: config !== false
- });
- };
- }
- catch (err) {
- builtInProp = function builtInProp(obj,name,val) {
- obj[name] = val;
- return obj;
- };
- }
- // Note: using a queue instead of array for efficiency
- scheduling_queue = (function Queue() {
- var first, last, item;
- function Item(fn,self) {
- this.fn = fn;
- this.self = self;
- this.next = void 0;
- }
- return {
- add: function add(fn,self) {
- item = new Item(fn,self);
- if (last) {
- last.next = item;
- }
- else {
- first = item;
- }
- last = item;
- item = void 0;
- },
- drain: function drain() {
- var f = first;
- first = last = cycle = void 0;
- while (f) {
- f.fn.call(f.self);
- f = f.next;
- }
- }
- };
- })();
- function schedule(fn,self) {
- scheduling_queue.add(fn,self);
- if (!cycle) {
- cycle = timer(scheduling_queue.drain);
- }
- }
- // promise duck typing
- function isThenable(o) {
- var _then, o_type = typeof o;
- if (o != null &&
- (
- o_type == "object" || o_type == "function"
- )
- ) {
- _then = o.then;
- }
- return typeof _then == "function" ? _then : false;
- }
- function notify() {
- for (var i=0; i<this.chain.length; i++) {
- notifyIsolated(
- this,
- (this.state === 1) ? this.chain[i].success : this.chain[i].failure,
- this.chain[i]
- );
- }
- this.chain.length = 0;
- }
- // NOTE: This is a separate function to isolate
- // the `try..catch` so that other code can be
- // optimized better
- function notifyIsolated(self,cb,chain) {
- var ret, _then;
- try {
- if (cb === false) {
- chain.reject(self.msg);
- }
- else {
- if (cb === true) {
- ret = self.msg;
- }
- else {
- ret = cb.call(void 0,self.msg);
- }
- if (ret === chain.promise) {
- chain.reject(TypeError("Promise-chain cycle"));
- }
- else if (_then = isThenable(ret)) {
- _then.call(ret,chain.resolve,chain.reject);
- }
- else {
- chain.resolve(ret);
- }
- }
- }
- catch (err) {
- chain.reject(err);
- }
- }
- function resolve(msg) {
- var _then, self = this;
- // already triggered?
- if (self.triggered) { return; }
- self.triggered = true;
- // unwrap
- if (self.def) {
- self = self.def;
- }
- try {
- if (_then = isThenable(msg)) {
- schedule(function(){
- var def_wrapper = new MakeDefWrapper(self);
- try {
- _then.call(msg,
- function $resolve$(){ resolve.apply(def_wrapper,arguments); },
- function $reject$(){ reject.apply(def_wrapper,arguments); }
- );
- }
- catch (err) {
- reject.call(def_wrapper,err);
- }
- })
- }
- else {
- self.msg = msg;
- self.state = 1;
- if (self.chain.length > 0) {
- schedule(notify,self);
- }
- }
- }
- catch (err) {
- reject.call(new MakeDefWrapper(self),err);
- }
- }
- function reject(msg) {
- var self = this;
- // already triggered?
- if (self.triggered) { return; }
- self.triggered = true;
- // unwrap
- if (self.def) {
- self = self.def;
- }
- self.msg = msg;
- self.state = 2;
- if (self.chain.length > 0) {
- schedule(notify,self);
- }
- }
- function iteratePromises(Constructor,arr,resolver,rejecter) {
- for (var idx=0; idx<arr.length; idx++) {
- (function IIFE(idx){
- Constructor.resolve(arr[idx])
- .then(
- function $resolver$(msg){
- resolver(idx,msg);
- },
- rejecter
- );
- })(idx);
- }
- }
- function MakeDefWrapper(self) {
- this.def = self;
- this.triggered = false;
- }
- function MakeDef(self) {
- this.promise = self;
- this.state = 0;
- this.triggered = false;
- this.chain = [];
- this.msg = void 0;
- }
- function Promise(executor) {
- if (typeof executor != "function") {
- throw TypeError("Not a function");
- }
- if (this.__NPO__ !== 0) {
- throw TypeError("Not a promise");
- }
- // instance shadowing the inherited "brand"
- // to signal an already "initialized" promise
- this.__NPO__ = 1;
- var def = new MakeDef(this);
- this["then"] = function then(success,failure) {
- var o = {
- success: typeof success == "function" ? success : true,
- failure: typeof failure == "function" ? failure : false
- };
- // Note: `then(..)` itself can be borrowed to be used against
- // a different promise constructor for making the chained promise,
- // by substituting a different `this` binding.
- o.promise = new this.constructor(function extractChain(resolve,reject) {
- if (typeof resolve != "function" || typeof reject != "function") {
- throw TypeError("Not a function");
- }
- o.resolve = resolve;
- o.reject = reject;
- });
- def.chain.push(o);
- if (def.state !== 0) {
- schedule(notify,def);
- }
- return o.promise;
- };
- this["catch"] = function $catch$(failure) {
- return this.then(void 0,failure);
- };
- try {
- executor.call(
- void 0,
- function publicResolve(msg){
- resolve.call(def,msg);
- },
- function publicReject(msg) {
- reject.call(def,msg);
- }
- );
- }
- catch (err) {
- reject.call(def,err);
- }
- }
- var PromisePrototype = builtInProp({},"constructor",Promise,
- /*configurable=*/false
- );
- // Note: Android 4 cannot use `Object.defineProperty(..)` here
- Promise.prototype = PromisePrototype;
- // built-in "brand" to signal an "uninitialized" promise
- builtInProp(PromisePrototype,"__NPO__",0,
- /*configurable=*/false
- );
- builtInProp(Promise,"resolve",function Promise$resolve(msg) {
- var Constructor = this;
- // spec mandated checks
- // note: best "isPromise" check that's practical for now
- if (msg && typeof msg == "object" && msg.__NPO__ === 1) {
- return msg;
- }
- return new Constructor(function executor(resolve,reject){
- if (typeof resolve != "function" || typeof reject != "function") {
- throw TypeError("Not a function");
- }
- resolve(msg);
- });
- });
- builtInProp(Promise,"reject",function Promise$reject(msg) {
- return new this(function executor(resolve,reject){
- if (typeof resolve != "function" || typeof reject != "function") {
- throw TypeError("Not a function");
- }
- reject(msg);
- });
- });
- builtInProp(Promise,"all",function Promise$all(arr) {
- var Constructor = this;
- // spec mandated checks
- if (ToString.call(arr) != "[object Array]") {
- return Constructor.reject(TypeError("Not an array"));
- }
- if (arr.length === 0) {
- return Constructor.resolve([]);
- }
- return new Constructor(function executor(resolve,reject){
- if (typeof resolve != "function" || typeof reject != "function") {
- throw TypeError("Not a function");
- }
- var len = arr.length, msgs = Array(len), count = 0;
- iteratePromises(Constructor,arr,function resolver(idx,msg) {
- msgs[idx] = msg;
- if (++count === len) {
- resolve(msgs);
- }
- },reject);
- });
- });
- builtInProp(Promise,"race",function Promise$race(arr) {
- var Constructor = this;
- // spec mandated checks
- if (ToString.call(arr) != "[object Array]") {
- return Constructor.reject(TypeError("Not an array"));
- }
- return new Constructor(function executor(resolve,reject){
- if (typeof resolve != "function" || typeof reject != "function") {
- throw TypeError("Not a function");
- }
- iteratePromises(Constructor,arr,function resolver(idx,msg){
- resolve(msg);
- },reject);
- });
- });
- return Promise;
- });
|