UNPKG

core-js

Version:
140 lines 4.68 kB
// ES6 promises shim // Based on https://github.com/getify/native-promise-only/ !function(Promise, test){ isFunction(Promise) && isFunction(Promise.resolve) && Promise.resolve(test = new Promise(Function())) == test || function(asap, DEF){ function isThenable(o){ var then; if(isObject(o))then = o.then; return isFunction(then) ? then : false; } function notify(def){ var chain = def.chain; chain.length && asap(function(){ var msg = def.msg , ok = def.state == 1 , i = 0; while(chain.length > i)!function(react){ var cb = ok ? react.ok : react.fail , ret, then; try { if(cb){ ret = cb === true ? msg : cb(msg); if(ret === react.P){ react.rej(TypeError(PROMISE + '-chain cycle')); } else if(then = isThenable(ret)){ then.call(ret, react.res, react.rej); } else react.res(ret); } else react.rej(msg); } catch(err){ react.rej(err); } }(chain[i++]); chain.length = 0; }); } function resolve(msg){ var def = this , then, wrapper; if(def.done)return; def.done = true; def = def.def || def; // unwrap try { if(then = isThenable(msg)){ wrapper = {def: def, done: false}; // wrap then.call(msg, ctx(resolve, wrapper, 1), ctx(reject, wrapper, 1)); } else { def.msg = msg; def.state = 1; notify(def); } } catch(err){ reject.call(wrapper || {def: def, done: false}, err); // wrap } } function reject(msg){ var def = this; if(def.done)return; def.done = true; def = def.def || def; // unwrap def.msg = msg; def.state = 2; notify(def); } // 25.4.3.1 Promise(executor) Promise = function(executor){ assertFunction(executor); assertInstance(this, Promise, PROMISE); var def = {chain: [], state: 0, done: false, msg: undefined}; hidden(this, DEF, def); try { executor(ctx(resolve, def, 1), ctx(reject, def, 1)); } catch(err){ reject.call(def, err); } } assignHidden(Promise[PROTOTYPE], { // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) then: function(onFulfilled, onRejected){ var react = { ok: isFunction(onFulfilled) ? onFulfilled : true, fail: isFunction(onRejected) ? onRejected : false } , P = react.P = new this[CONSTRUCTOR](function(resolve, reject){ react.res = assertFunction(resolve); react.rej = assertFunction(reject); }), def = this[DEF]; def.chain.push(react); def.state && notify(def); return P; }, // 25.4.5.1 Promise.prototype.catch(onRejected) 'catch': function(onRejected){ return this.then(undefined, onRejected); } }); assignHidden(Promise, { // 25.4.4.1 Promise.all(iterable) all: function(iterable){ var Promise = this , values = []; return new Promise(function(resolve, reject){ forOf(iterable, false, push, values); var remaining = values.length , results = Array(remaining); if(remaining)forEach.call(values, function(promise, index){ Promise.resolve(promise).then(function(value){ results[index] = value; --remaining || resolve(results); }, reject); }); else resolve(results); }); }, // 25.4.4.4 Promise.race(iterable) race: function(iterable){ var Promise = this; return new Promise(function(resolve, reject){ forOf(iterable, false, function(promise){ Promise.resolve(promise).then(resolve, reject); }); }); }, // 25.4.4.5 Promise.reject(r) reject: function(r){ return new this(function(resolve, reject){ reject(r); }); }, // 25.4.4.6 Promise.resolve(x) resolve: function(x){ return isObject(x) && getPrototypeOf(x) === this[PROTOTYPE] ? x : new this(function(resolve, reject){ resolve(x); }); } }); }(nextTick || setImmediate, safeSymbol('def')); setToStringTag(Promise, PROMISE); $define(GLOBAL + FORCED * !isNative(Promise), {Promise: Promise}); }(global[PROMISE]);