1 | 'use strict';
|
2 | var $ = require('../internals/export');
|
3 | var IS_PURE = require('../internals/is-pure');
|
4 | var global = require('../internals/global');
|
5 | var getBuiltIn = require('../internals/get-built-in');
|
6 | var NativePromise = require('../internals/native-promise-constructor');
|
7 | var redefine = require('../internals/redefine');
|
8 | var redefineAll = require('../internals/redefine-all');
|
9 | var setToStringTag = require('../internals/set-to-string-tag');
|
10 | var setSpecies = require('../internals/set-species');
|
11 | var isObject = require('../internals/is-object');
|
12 | var aFunction = require('../internals/a-function');
|
13 | var anInstance = require('../internals/an-instance');
|
14 | var classof = require('../internals/classof-raw');
|
15 | var iterate = require('../internals/iterate');
|
16 | var checkCorrectnessOfIteration = require('../internals/check-correctness-of-iteration');
|
17 | var speciesConstructor = require('../internals/species-constructor');
|
18 | var task = require('../internals/task').set;
|
19 | var microtask = require('../internals/microtask');
|
20 | var promiseResolve = require('../internals/promise-resolve');
|
21 | var hostReportErrors = require('../internals/host-report-errors');
|
22 | var newPromiseCapabilityModule = require('../internals/new-promise-capability');
|
23 | var perform = require('../internals/perform');
|
24 | var InternalStateModule = require('../internals/internal-state');
|
25 | var isForced = require('../internals/is-forced');
|
26 | var wellKnownSymbol = require('../internals/well-known-symbol');
|
27 | var V8_VERSION = require('../internals/v8-version');
|
28 |
|
29 | var SPECIES = wellKnownSymbol('species');
|
30 | var PROMISE = 'Promise';
|
31 | var getInternalState = InternalStateModule.get;
|
32 | var setInternalState = InternalStateModule.set;
|
33 | var getInternalPromiseState = InternalStateModule.getterFor(PROMISE);
|
34 | var PromiseConstructor = NativePromise;
|
35 | var TypeError = global.TypeError;
|
36 | var document = global.document;
|
37 | var process = global.process;
|
38 | var $fetch = getBuiltIn('fetch');
|
39 | var newPromiseCapability = newPromiseCapabilityModule.f;
|
40 | var newGenericPromiseCapability = newPromiseCapability;
|
41 | var IS_NODE = classof(process) == 'process';
|
42 | var DISPATCH_EVENT = !!(document && document.createEvent && global.dispatchEvent);
|
43 | var UNHANDLED_REJECTION = 'unhandledrejection';
|
44 | var REJECTION_HANDLED = 'rejectionhandled';
|
45 | var PENDING = 0;
|
46 | var FULFILLED = 1;
|
47 | var REJECTED = 2;
|
48 | var HANDLED = 1;
|
49 | var UNHANDLED = 2;
|
50 | var Internal, OwnPromiseCapability, PromiseWrapper, nativeThen;
|
51 |
|
52 | var FORCED = isForced(PROMISE, function () {
|
53 |
|
54 | var promise = PromiseConstructor.resolve(1);
|
55 | var empty = function () { };
|
56 | var FakePromise = (promise.constructor = {})[SPECIES] = function (exec) {
|
57 | exec(empty, empty);
|
58 | };
|
59 |
|
60 | return !((IS_NODE || typeof PromiseRejectionEvent == 'function')
|
61 | && (!IS_PURE || promise['finally'])
|
62 | && promise.then(empty) instanceof FakePromise
|
63 |
|
64 |
|
65 |
|
66 | && V8_VERSION !== 66);
|
67 | });
|
68 |
|
69 | var INCORRECT_ITERATION = FORCED || !checkCorrectnessOfIteration(function (iterable) {
|
70 | PromiseConstructor.all(iterable)['catch'](function () { });
|
71 | });
|
72 |
|
73 |
|
74 | var isThenable = function (it) {
|
75 | var then;
|
76 | return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
|
77 | };
|
78 |
|
79 | var notify = function (promise, state, isReject) {
|
80 | if (state.notified) return;
|
81 | state.notified = true;
|
82 | var chain = state.reactions;
|
83 | microtask(function () {
|
84 | var value = state.value;
|
85 | var ok = state.state == FULFILLED;
|
86 | var index = 0;
|
87 |
|
88 | while (chain.length > index) {
|
89 | var reaction = chain[index++];
|
90 | var handler = ok ? reaction.ok : reaction.fail;
|
91 | var resolve = reaction.resolve;
|
92 | var reject = reaction.reject;
|
93 | var domain = reaction.domain;
|
94 | var result, then, exited;
|
95 | try {
|
96 | if (handler) {
|
97 | if (!ok) {
|
98 | if (state.rejection === UNHANDLED) onHandleUnhandled(promise, state);
|
99 | state.rejection = HANDLED;
|
100 | }
|
101 | if (handler === true) result = value;
|
102 | else {
|
103 | if (domain) domain.enter();
|
104 | result = handler(value);
|
105 | if (domain) {
|
106 | domain.exit();
|
107 | exited = true;
|
108 | }
|
109 | }
|
110 | if (result === reaction.promise) {
|
111 | reject(TypeError('Promise-chain cycle'));
|
112 | } else if (then = isThenable(result)) {
|
113 | then.call(result, resolve, reject);
|
114 | } else resolve(result);
|
115 | } else reject(value);
|
116 | } catch (error) {
|
117 | if (domain && !exited) domain.exit();
|
118 | reject(error);
|
119 | }
|
120 | }
|
121 | state.reactions = [];
|
122 | state.notified = false;
|
123 | if (isReject && !state.rejection) onUnhandled(promise, state);
|
124 | });
|
125 | };
|
126 |
|
127 | var dispatchEvent = function (name, promise, reason) {
|
128 | var event, handler;
|
129 | if (DISPATCH_EVENT) {
|
130 | event = document.createEvent('Event');
|
131 | event.promise = promise;
|
132 | event.reason = reason;
|
133 | event.initEvent(name, false, true);
|
134 | global.dispatchEvent(event);
|
135 | } else event = { promise: promise, reason: reason };
|
136 | if (handler = global['on' + name]) handler(event);
|
137 | else if (name === UNHANDLED_REJECTION) hostReportErrors('Unhandled promise rejection', reason);
|
138 | };
|
139 |
|
140 | var onUnhandled = function (promise, state) {
|
141 | task.call(global, function () {
|
142 | var value = state.value;
|
143 | var IS_UNHANDLED = isUnhandled(state);
|
144 | var result;
|
145 | if (IS_UNHANDLED) {
|
146 | result = perform(function () {
|
147 | if (IS_NODE) {
|
148 | process.emit('unhandledRejection', value, promise);
|
149 | } else dispatchEvent(UNHANDLED_REJECTION, promise, value);
|
150 | });
|
151 |
|
152 | state.rejection = IS_NODE || isUnhandled(state) ? UNHANDLED : HANDLED;
|
153 | if (result.error) throw result.value;
|
154 | }
|
155 | });
|
156 | };
|
157 |
|
158 | var isUnhandled = function (state) {
|
159 | return state.rejection !== HANDLED && !state.parent;
|
160 | };
|
161 |
|
162 | var onHandleUnhandled = function (promise, state) {
|
163 | task.call(global, function () {
|
164 | if (IS_NODE) {
|
165 | process.emit('rejectionHandled', promise);
|
166 | } else dispatchEvent(REJECTION_HANDLED, promise, state.value);
|
167 | });
|
168 | };
|
169 |
|
170 | var bind = function (fn, promise, state, unwrap) {
|
171 | return function (value) {
|
172 | fn(promise, state, value, unwrap);
|
173 | };
|
174 | };
|
175 |
|
176 | var internalReject = function (promise, state, value, unwrap) {
|
177 | if (state.done) return;
|
178 | state.done = true;
|
179 | if (unwrap) state = unwrap;
|
180 | state.value = value;
|
181 | state.state = REJECTED;
|
182 | notify(promise, state, true);
|
183 | };
|
184 |
|
185 | var internalResolve = function (promise, state, value, unwrap) {
|
186 | if (state.done) return;
|
187 | state.done = true;
|
188 | if (unwrap) state = unwrap;
|
189 | try {
|
190 | if (promise === value) throw TypeError("Promise can't be resolved itself");
|
191 | var then = isThenable(value);
|
192 | if (then) {
|
193 | microtask(function () {
|
194 | var wrapper = { done: false };
|
195 | try {
|
196 | then.call(value,
|
197 | bind(internalResolve, promise, wrapper, state),
|
198 | bind(internalReject, promise, wrapper, state)
|
199 | );
|
200 | } catch (error) {
|
201 | internalReject(promise, wrapper, error, state);
|
202 | }
|
203 | });
|
204 | } else {
|
205 | state.value = value;
|
206 | state.state = FULFILLED;
|
207 | notify(promise, state, false);
|
208 | }
|
209 | } catch (error) {
|
210 | internalReject(promise, { done: false }, error, state);
|
211 | }
|
212 | };
|
213 |
|
214 |
|
215 | if (FORCED) {
|
216 |
|
217 | PromiseConstructor = function Promise(executor) {
|
218 | anInstance(this, PromiseConstructor, PROMISE);
|
219 | aFunction(executor);
|
220 | Internal.call(this);
|
221 | var state = getInternalState(this);
|
222 | try {
|
223 | executor(bind(internalResolve, this, state), bind(internalReject, this, state));
|
224 | } catch (error) {
|
225 | internalReject(this, state, error);
|
226 | }
|
227 | };
|
228 |
|
229 | Internal = function Promise(executor) {
|
230 | setInternalState(this, {
|
231 | type: PROMISE,
|
232 | done: false,
|
233 | notified: false,
|
234 | parent: false,
|
235 | reactions: [],
|
236 | rejection: false,
|
237 | state: PENDING,
|
238 | value: undefined
|
239 | });
|
240 | };
|
241 | Internal.prototype = redefineAll(PromiseConstructor.prototype, {
|
242 |
|
243 |
|
244 | then: function then(onFulfilled, onRejected) {
|
245 | var state = getInternalPromiseState(this);
|
246 | var reaction = newPromiseCapability(speciesConstructor(this, PromiseConstructor));
|
247 | reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
|
248 | reaction.fail = typeof onRejected == 'function' && onRejected;
|
249 | reaction.domain = IS_NODE ? process.domain : undefined;
|
250 | state.parent = true;
|
251 | state.reactions.push(reaction);
|
252 | if (state.state != PENDING) notify(this, state, false);
|
253 | return reaction.promise;
|
254 | },
|
255 |
|
256 |
|
257 | 'catch': function (onRejected) {
|
258 | return this.then(undefined, onRejected);
|
259 | }
|
260 | });
|
261 | OwnPromiseCapability = function () {
|
262 | var promise = new Internal();
|
263 | var state = getInternalState(promise);
|
264 | this.promise = promise;
|
265 | this.resolve = bind(internalResolve, promise, state);
|
266 | this.reject = bind(internalReject, promise, state);
|
267 | };
|
268 | newPromiseCapabilityModule.f = newPromiseCapability = function (C) {
|
269 | return C === PromiseConstructor || C === PromiseWrapper
|
270 | ? new OwnPromiseCapability(C)
|
271 | : newGenericPromiseCapability(C);
|
272 | };
|
273 |
|
274 | if (!IS_PURE && typeof NativePromise == 'function') {
|
275 | nativeThen = NativePromise.prototype.then;
|
276 |
|
277 |
|
278 | redefine(NativePromise.prototype, 'then', function then(onFulfilled, onRejected) {
|
279 | var that = this;
|
280 | return new PromiseConstructor(function (resolve, reject) {
|
281 | nativeThen.call(that, resolve, reject);
|
282 | }).then(onFulfilled, onRejected);
|
283 |
|
284 | }, { unsafe: true });
|
285 |
|
286 |
|
287 | if (typeof $fetch == 'function') $({ global: true, enumerable: true, forced: true }, {
|
288 |
|
289 | fetch: function fetch(input /* , init */) {
|
290 | return promiseResolve(PromiseConstructor, $fetch.apply(global, arguments));
|
291 | }
|
292 | });
|
293 | }
|
294 | }
|
295 |
|
296 | $({ global: true, wrap: true, forced: FORCED }, {
|
297 | Promise: PromiseConstructor
|
298 | });
|
299 |
|
300 | setToStringTag(PromiseConstructor, PROMISE, false, true);
|
301 | setSpecies(PROMISE);
|
302 |
|
303 | PromiseWrapper = getBuiltIn(PROMISE);
|
304 |
|
305 |
|
306 | $({ target: PROMISE, stat: true, forced: FORCED }, {
|
307 |
|
308 |
|
309 | reject: function reject(r) {
|
310 | var capability = newPromiseCapability(this);
|
311 | capability.reject.call(undefined, r);
|
312 | return capability.promise;
|
313 | }
|
314 | });
|
315 |
|
316 | $({ target: PROMISE, stat: true, forced: IS_PURE || FORCED }, {
|
317 |
|
318 |
|
319 | resolve: function resolve(x) {
|
320 | return promiseResolve(IS_PURE && this === PromiseWrapper ? PromiseConstructor : this, x);
|
321 | }
|
322 | });
|
323 |
|
324 | $({ target: PROMISE, stat: true, forced: INCORRECT_ITERATION }, {
|
325 |
|
326 |
|
327 | all: function all(iterable) {
|
328 | var C = this;
|
329 | var capability = newPromiseCapability(C);
|
330 | var resolve = capability.resolve;
|
331 | var reject = capability.reject;
|
332 | var result = perform(function () {
|
333 | var $promiseResolve = aFunction(C.resolve);
|
334 | var values = [];
|
335 | var counter = 0;
|
336 | var remaining = 1;
|
337 | iterate(iterable, function (promise) {
|
338 | var index = counter++;
|
339 | var alreadyCalled = false;
|
340 | values.push(undefined);
|
341 | remaining++;
|
342 | $promiseResolve.call(C, promise).then(function (value) {
|
343 | if (alreadyCalled) return;
|
344 | alreadyCalled = true;
|
345 | values[index] = value;
|
346 | --remaining || resolve(values);
|
347 | }, reject);
|
348 | });
|
349 | --remaining || resolve(values);
|
350 | });
|
351 | if (result.error) reject(result.value);
|
352 | return capability.promise;
|
353 | },
|
354 |
|
355 |
|
356 | race: function race(iterable) {
|
357 | var C = this;
|
358 | var capability = newPromiseCapability(C);
|
359 | var reject = capability.reject;
|
360 | var result = perform(function () {
|
361 | var $promiseResolve = aFunction(C.resolve);
|
362 | iterate(iterable, function (promise) {
|
363 | $promiseResolve.call(C, promise).then(capability.resolve, reject);
|
364 | });
|
365 | });
|
366 | if (result.error) reject(result.value);
|
367 | return capability.promise;
|
368 | }
|
369 | });
|