You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							379 lines
						
					
					
						
							13 KiB
						
					
					
				
			
		
		
	
	
							379 lines
						
					
					
						
							13 KiB
						
					
					
				'use strict'; | 
						|
var $ = require('../internals/export'); | 
						|
var IS_PURE = require('../internals/is-pure'); | 
						|
var global = require('../internals/global'); | 
						|
var getBuiltIn = require('../internals/get-built-in'); | 
						|
var NativePromise = require('../internals/native-promise-constructor'); | 
						|
var redefine = require('../internals/redefine'); | 
						|
var redefineAll = require('../internals/redefine-all'); | 
						|
var setToStringTag = require('../internals/set-to-string-tag'); | 
						|
var setSpecies = require('../internals/set-species'); | 
						|
var isObject = require('../internals/is-object'); | 
						|
var aFunction = require('../internals/a-function'); | 
						|
var anInstance = require('../internals/an-instance'); | 
						|
var classof = require('../internals/classof-raw'); | 
						|
var inspectSource = require('../internals/inspect-source'); | 
						|
var iterate = require('../internals/iterate'); | 
						|
var checkCorrectnessOfIteration = require('../internals/check-correctness-of-iteration'); | 
						|
var speciesConstructor = require('../internals/species-constructor'); | 
						|
var task = require('../internals/task').set; | 
						|
var microtask = require('../internals/microtask'); | 
						|
var promiseResolve = require('../internals/promise-resolve'); | 
						|
var hostReportErrors = require('../internals/host-report-errors'); | 
						|
var newPromiseCapabilityModule = require('../internals/new-promise-capability'); | 
						|
var perform = require('../internals/perform'); | 
						|
var InternalStateModule = require('../internals/internal-state'); | 
						|
var isForced = require('../internals/is-forced'); | 
						|
var wellKnownSymbol = require('../internals/well-known-symbol'); | 
						|
var V8_VERSION = require('../internals/engine-v8-version'); | 
						|
 | 
						|
var SPECIES = wellKnownSymbol('species'); | 
						|
var PROMISE = 'Promise'; | 
						|
var getInternalState = InternalStateModule.get; | 
						|
var setInternalState = InternalStateModule.set; | 
						|
var getInternalPromiseState = InternalStateModule.getterFor(PROMISE); | 
						|
var PromiseConstructor = NativePromise; | 
						|
var TypeError = global.TypeError; | 
						|
var document = global.document; | 
						|
var process = global.process; | 
						|
var $fetch = getBuiltIn('fetch'); | 
						|
var newPromiseCapability = newPromiseCapabilityModule.f; | 
						|
var newGenericPromiseCapability = newPromiseCapability; | 
						|
var IS_NODE = classof(process) == 'process'; | 
						|
var DISPATCH_EVENT = !!(document && document.createEvent && global.dispatchEvent); | 
						|
var UNHANDLED_REJECTION = 'unhandledrejection'; | 
						|
var REJECTION_HANDLED = 'rejectionhandled'; | 
						|
var PENDING = 0; | 
						|
var FULFILLED = 1; | 
						|
var REJECTED = 2; | 
						|
var HANDLED = 1; | 
						|
var UNHANDLED = 2; | 
						|
var Internal, OwnPromiseCapability, PromiseWrapper, nativeThen; | 
						|
 | 
						|
var FORCED = isForced(PROMISE, function () { | 
						|
  var GLOBAL_CORE_JS_PROMISE = inspectSource(PromiseConstructor) !== String(PromiseConstructor); | 
						|
  if (!GLOBAL_CORE_JS_PROMISE) { | 
						|
    // V8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables | 
						|
    // https://bugs.chromium.org/p/chromium/issues/detail?id=830565 | 
						|
    // We can't detect it synchronously, so just check versions | 
						|
    if (V8_VERSION === 66) return true; | 
						|
    // Unhandled rejections tracking support, NodeJS Promise without it fails @@species test | 
						|
    if (!IS_NODE && typeof PromiseRejectionEvent != 'function') return true; | 
						|
  } | 
						|
  // We need Promise#finally in the pure version for preventing prototype pollution | 
						|
  if (IS_PURE && !PromiseConstructor.prototype['finally']) return true; | 
						|
  // We can't use @@species feature detection in V8 since it causes | 
						|
  // deoptimization and performance degradation | 
						|
  // https://github.com/zloirock/core-js/issues/679 | 
						|
  if (V8_VERSION >= 51 && /native code/.test(PromiseConstructor)) return false; | 
						|
  // Detect correctness of subclassing with @@species support | 
						|
  var promise = PromiseConstructor.resolve(1); | 
						|
  var FakePromise = function (exec) { | 
						|
    exec(function () { /* empty */ }, function () { /* empty */ }); | 
						|
  }; | 
						|
  var constructor = promise.constructor = {}; | 
						|
  constructor[SPECIES] = FakePromise; | 
						|
  return !(promise.then(function () { /* empty */ }) instanceof FakePromise); | 
						|
}); | 
						|
 | 
						|
var INCORRECT_ITERATION = FORCED || !checkCorrectnessOfIteration(function (iterable) { | 
						|
  PromiseConstructor.all(iterable)['catch'](function () { /* empty */ }); | 
						|
}); | 
						|
 | 
						|
// helpers | 
						|
var isThenable = function (it) { | 
						|
  var then; | 
						|
  return isObject(it) && typeof (then = it.then) == 'function' ? then : false; | 
						|
}; | 
						|
 | 
						|
var notify = function (promise, state, isReject) { | 
						|
  if (state.notified) return; | 
						|
  state.notified = true; | 
						|
  var chain = state.reactions; | 
						|
  microtask(function () { | 
						|
    var value = state.value; | 
						|
    var ok = state.state == FULFILLED; | 
						|
    var index = 0; | 
						|
    // variable length - can't use forEach | 
						|
    while (chain.length > index) { | 
						|
      var reaction = chain[index++]; | 
						|
      var handler = ok ? reaction.ok : reaction.fail; | 
						|
      var resolve = reaction.resolve; | 
						|
      var reject = reaction.reject; | 
						|
      var domain = reaction.domain; | 
						|
      var result, then, exited; | 
						|
      try { | 
						|
        if (handler) { | 
						|
          if (!ok) { | 
						|
            if (state.rejection === UNHANDLED) onHandleUnhandled(promise, state); | 
						|
            state.rejection = HANDLED; | 
						|
          } | 
						|
          if (handler === true) result = value; | 
						|
          else { | 
						|
            if (domain) domain.enter(); | 
						|
            result = handler(value); // can throw | 
						|
            if (domain) { | 
						|
              domain.exit(); | 
						|
              exited = true; | 
						|
            } | 
						|
          } | 
						|
          if (result === reaction.promise) { | 
						|
            reject(TypeError('Promise-chain cycle')); | 
						|
          } else if (then = isThenable(result)) { | 
						|
            then.call(result, resolve, reject); | 
						|
          } else resolve(result); | 
						|
        } else reject(value); | 
						|
      } catch (error) { | 
						|
        if (domain && !exited) domain.exit(); | 
						|
        reject(error); | 
						|
      } | 
						|
    } | 
						|
    state.reactions = []; | 
						|
    state.notified = false; | 
						|
    if (isReject && !state.rejection) onUnhandled(promise, state); | 
						|
  }); | 
						|
}; | 
						|
 | 
						|
var dispatchEvent = function (name, promise, reason) { | 
						|
  var event, handler; | 
						|
  if (DISPATCH_EVENT) { | 
						|
    event = document.createEvent('Event'); | 
						|
    event.promise = promise; | 
						|
    event.reason = reason; | 
						|
    event.initEvent(name, false, true); | 
						|
    global.dispatchEvent(event); | 
						|
  } else event = { promise: promise, reason: reason }; | 
						|
  if (handler = global['on' + name]) handler(event); | 
						|
  else if (name === UNHANDLED_REJECTION) hostReportErrors('Unhandled promise rejection', reason); | 
						|
}; | 
						|
 | 
						|
var onUnhandled = function (promise, state) { | 
						|
  task.call(global, function () { | 
						|
    var value = state.value; | 
						|
    var IS_UNHANDLED = isUnhandled(state); | 
						|
    var result; | 
						|
    if (IS_UNHANDLED) { | 
						|
      result = perform(function () { | 
						|
        if (IS_NODE) { | 
						|
          process.emit('unhandledRejection', value, promise); | 
						|
        } else dispatchEvent(UNHANDLED_REJECTION, promise, value); | 
						|
      }); | 
						|
      // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should | 
						|
      state.rejection = IS_NODE || isUnhandled(state) ? UNHANDLED : HANDLED; | 
						|
      if (result.error) throw result.value; | 
						|
    } | 
						|
  }); | 
						|
}; | 
						|
 | 
						|
var isUnhandled = function (state) { | 
						|
  return state.rejection !== HANDLED && !state.parent; | 
						|
}; | 
						|
 | 
						|
var onHandleUnhandled = function (promise, state) { | 
						|
  task.call(global, function () { | 
						|
    if (IS_NODE) { | 
						|
      process.emit('rejectionHandled', promise); | 
						|
    } else dispatchEvent(REJECTION_HANDLED, promise, state.value); | 
						|
  }); | 
						|
}; | 
						|
 | 
						|
var bind = function (fn, promise, state, unwrap) { | 
						|
  return function (value) { | 
						|
    fn(promise, state, value, unwrap); | 
						|
  }; | 
						|
}; | 
						|
 | 
						|
var internalReject = function (promise, state, value, unwrap) { | 
						|
  if (state.done) return; | 
						|
  state.done = true; | 
						|
  if (unwrap) state = unwrap; | 
						|
  state.value = value; | 
						|
  state.state = REJECTED; | 
						|
  notify(promise, state, true); | 
						|
}; | 
						|
 | 
						|
var internalResolve = function (promise, state, value, unwrap) { | 
						|
  if (state.done) return; | 
						|
  state.done = true; | 
						|
  if (unwrap) state = unwrap; | 
						|
  try { | 
						|
    if (promise === value) throw TypeError("Promise can't be resolved itself"); | 
						|
    var then = isThenable(value); | 
						|
    if (then) { | 
						|
      microtask(function () { | 
						|
        var wrapper = { done: false }; | 
						|
        try { | 
						|
          then.call(value, | 
						|
            bind(internalResolve, promise, wrapper, state), | 
						|
            bind(internalReject, promise, wrapper, state) | 
						|
          ); | 
						|
        } catch (error) { | 
						|
          internalReject(promise, wrapper, error, state); | 
						|
        } | 
						|
      }); | 
						|
    } else { | 
						|
      state.value = value; | 
						|
      state.state = FULFILLED; | 
						|
      notify(promise, state, false); | 
						|
    } | 
						|
  } catch (error) { | 
						|
    internalReject(promise, { done: false }, error, state); | 
						|
  } | 
						|
}; | 
						|
 | 
						|
// constructor polyfill | 
						|
if (FORCED) { | 
						|
  // 25.4.3.1 Promise(executor) | 
						|
  PromiseConstructor = function Promise(executor) { | 
						|
    anInstance(this, PromiseConstructor, PROMISE); | 
						|
    aFunction(executor); | 
						|
    Internal.call(this); | 
						|
    var state = getInternalState(this); | 
						|
    try { | 
						|
      executor(bind(internalResolve, this, state), bind(internalReject, this, state)); | 
						|
    } catch (error) { | 
						|
      internalReject(this, state, error); | 
						|
    } | 
						|
  }; | 
						|
  // eslint-disable-next-line no-unused-vars | 
						|
  Internal = function Promise(executor) { | 
						|
    setInternalState(this, { | 
						|
      type: PROMISE, | 
						|
      done: false, | 
						|
      notified: false, | 
						|
      parent: false, | 
						|
      reactions: [], | 
						|
      rejection: false, | 
						|
      state: PENDING, | 
						|
      value: undefined | 
						|
    }); | 
						|
  }; | 
						|
  Internal.prototype = redefineAll(PromiseConstructor.prototype, { | 
						|
    // `Promise.prototype.then` method | 
						|
    // https://tc39.github.io/ecma262/#sec-promise.prototype.then | 
						|
    then: function then(onFulfilled, onRejected) { | 
						|
      var state = getInternalPromiseState(this); | 
						|
      var reaction = newPromiseCapability(speciesConstructor(this, PromiseConstructor)); | 
						|
      reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; | 
						|
      reaction.fail = typeof onRejected == 'function' && onRejected; | 
						|
      reaction.domain = IS_NODE ? process.domain : undefined; | 
						|
      state.parent = true; | 
						|
      state.reactions.push(reaction); | 
						|
      if (state.state != PENDING) notify(this, state, false); | 
						|
      return reaction.promise; | 
						|
    }, | 
						|
    // `Promise.prototype.catch` method | 
						|
    // https://tc39.github.io/ecma262/#sec-promise.prototype.catch | 
						|
    'catch': function (onRejected) { | 
						|
      return this.then(undefined, onRejected); | 
						|
    } | 
						|
  }); | 
						|
  OwnPromiseCapability = function () { | 
						|
    var promise = new Internal(); | 
						|
    var state = getInternalState(promise); | 
						|
    this.promise = promise; | 
						|
    this.resolve = bind(internalResolve, promise, state); | 
						|
    this.reject = bind(internalReject, promise, state); | 
						|
  }; | 
						|
  newPromiseCapabilityModule.f = newPromiseCapability = function (C) { | 
						|
    return C === PromiseConstructor || C === PromiseWrapper | 
						|
      ? new OwnPromiseCapability(C) | 
						|
      : newGenericPromiseCapability(C); | 
						|
  }; | 
						|
 | 
						|
  if (!IS_PURE && typeof NativePromise == 'function') { | 
						|
    nativeThen = NativePromise.prototype.then; | 
						|
 | 
						|
    // wrap native Promise#then for native async functions | 
						|
    redefine(NativePromise.prototype, 'then', function then(onFulfilled, onRejected) { | 
						|
      var that = this; | 
						|
      return new PromiseConstructor(function (resolve, reject) { | 
						|
        nativeThen.call(that, resolve, reject); | 
						|
      }).then(onFulfilled, onRejected); | 
						|
    // https://github.com/zloirock/core-js/issues/640 | 
						|
    }, { unsafe: true }); | 
						|
 | 
						|
    // wrap fetch result | 
						|
    if (typeof $fetch == 'function') $({ global: true, enumerable: true, forced: true }, { | 
						|
      // eslint-disable-next-line no-unused-vars | 
						|
      fetch: function fetch(input /* , init */) { | 
						|
        return promiseResolve(PromiseConstructor, $fetch.apply(global, arguments)); | 
						|
      } | 
						|
    }); | 
						|
  } | 
						|
} | 
						|
 | 
						|
$({ global: true, wrap: true, forced: FORCED }, { | 
						|
  Promise: PromiseConstructor | 
						|
}); | 
						|
 | 
						|
setToStringTag(PromiseConstructor, PROMISE, false, true); | 
						|
setSpecies(PROMISE); | 
						|
 | 
						|
PromiseWrapper = getBuiltIn(PROMISE); | 
						|
 | 
						|
// statics | 
						|
$({ target: PROMISE, stat: true, forced: FORCED }, { | 
						|
  // `Promise.reject` method | 
						|
  // https://tc39.github.io/ecma262/#sec-promise.reject | 
						|
  reject: function reject(r) { | 
						|
    var capability = newPromiseCapability(this); | 
						|
    capability.reject.call(undefined, r); | 
						|
    return capability.promise; | 
						|
  } | 
						|
}); | 
						|
 | 
						|
$({ target: PROMISE, stat: true, forced: IS_PURE || FORCED }, { | 
						|
  // `Promise.resolve` method | 
						|
  // https://tc39.github.io/ecma262/#sec-promise.resolve | 
						|
  resolve: function resolve(x) { | 
						|
    return promiseResolve(IS_PURE && this === PromiseWrapper ? PromiseConstructor : this, x); | 
						|
  } | 
						|
}); | 
						|
 | 
						|
$({ target: PROMISE, stat: true, forced: INCORRECT_ITERATION }, { | 
						|
  // `Promise.all` method | 
						|
  // https://tc39.github.io/ecma262/#sec-promise.all | 
						|
  all: function all(iterable) { | 
						|
    var C = this; | 
						|
    var capability = newPromiseCapability(C); | 
						|
    var resolve = capability.resolve; | 
						|
    var reject = capability.reject; | 
						|
    var result = perform(function () { | 
						|
      var $promiseResolve = aFunction(C.resolve); | 
						|
      var values = []; | 
						|
      var counter = 0; | 
						|
      var remaining = 1; | 
						|
      iterate(iterable, function (promise) { | 
						|
        var index = counter++; | 
						|
        var alreadyCalled = false; | 
						|
        values.push(undefined); | 
						|
        remaining++; | 
						|
        $promiseResolve.call(C, promise).then(function (value) { | 
						|
          if (alreadyCalled) return; | 
						|
          alreadyCalled = true; | 
						|
          values[index] = value; | 
						|
          --remaining || resolve(values); | 
						|
        }, reject); | 
						|
      }); | 
						|
      --remaining || resolve(values); | 
						|
    }); | 
						|
    if (result.error) reject(result.value); | 
						|
    return capability.promise; | 
						|
  }, | 
						|
  // `Promise.race` method | 
						|
  // https://tc39.github.io/ecma262/#sec-promise.race | 
						|
  race: function race(iterable) { | 
						|
    var C = this; | 
						|
    var capability = newPromiseCapability(C); | 
						|
    var reject = capability.reject; | 
						|
    var result = perform(function () { | 
						|
      var $promiseResolve = aFunction(C.resolve); | 
						|
      iterate(iterable, function (promise) { | 
						|
        $promiseResolve.call(C, promise).then(capability.resolve, reject); | 
						|
      }); | 
						|
    }); | 
						|
    if (result.error) reject(result.value); | 
						|
    return capability.promise; | 
						|
  } | 
						|
});
 | 
						|
 |