1 | 'use strict';
|
2 | var $ = require('../internals/export');
|
3 | var IS_PURE = require('../internals/is-pure');
|
4 | var IS_NODE = require('../internals/engine-is-node');
|
5 | var global = require('../internals/global');
|
6 | var call = require('../internals/function-call');
|
7 | var defineBuiltIn = require('../internals/define-built-in');
|
8 | var setPrototypeOf = require('../internals/object-set-prototype-of');
|
9 | var setToStringTag = require('../internals/set-to-string-tag');
|
10 | var setSpecies = require('../internals/set-species');
|
11 | var aCallable = require('../internals/a-callable');
|
12 | var isCallable = require('../internals/is-callable');
|
13 | var isObject = require('../internals/is-object');
|
14 | var anInstance = require('../internals/an-instance');
|
15 | var speciesConstructor = require('../internals/species-constructor');
|
16 | var task = require('../internals/task').set;
|
17 | var microtask = require('../internals/microtask');
|
18 | var hostReportErrors = require('../internals/host-report-errors');
|
19 | var perform = require('../internals/perform');
|
20 | var Queue = require('../internals/queue');
|
21 | var InternalStateModule = require('../internals/internal-state');
|
22 | var NativePromiseConstructor = require('../internals/promise-native-constructor');
|
23 | var PromiseConstructorDetection = require('../internals/promise-constructor-detection');
|
24 | var newPromiseCapabilityModule = require('../internals/new-promise-capability');
|
25 |
|
26 | var PROMISE = 'Promise';
|
27 | var FORCED_PROMISE_CONSTRUCTOR = PromiseConstructorDetection.CONSTRUCTOR;
|
28 | var NATIVE_PROMISE_REJECTION_EVENT = PromiseConstructorDetection.REJECTION_EVENT;
|
29 | var NATIVE_PROMISE_SUBCLASSING = PromiseConstructorDetection.SUBCLASSING;
|
30 | var getInternalPromiseState = InternalStateModule.getterFor(PROMISE);
|
31 | var setInternalState = InternalStateModule.set;
|
32 | var NativePromisePrototype = NativePromiseConstructor && NativePromiseConstructor.prototype;
|
33 | var PromiseConstructor = NativePromiseConstructor;
|
34 | var PromisePrototype = NativePromisePrototype;
|
35 | var TypeError = global.TypeError;
|
36 | var document = global.document;
|
37 | var process = global.process;
|
38 | var newPromiseCapability = newPromiseCapabilityModule.f;
|
39 | var newGenericPromiseCapability = newPromiseCapability;
|
40 |
|
41 | var DISPATCH_EVENT = !!(document && document.createEvent && global.dispatchEvent);
|
42 | var UNHANDLED_REJECTION = 'unhandledrejection';
|
43 | var REJECTION_HANDLED = 'rejectionhandled';
|
44 | var PENDING = 0;
|
45 | var FULFILLED = 1;
|
46 | var REJECTED = 2;
|
47 | var HANDLED = 1;
|
48 | var UNHANDLED = 2;
|
49 |
|
50 | var Internal, OwnPromiseCapability, PromiseWrapper, nativeThen;
|
51 |
|
52 |
|
53 | var isThenable = function (it) {
|
54 | var then;
|
55 | return isObject(it) && isCallable(then = it.then) ? then : false;
|
56 | };
|
57 |
|
58 | var callReaction = function (reaction, state) {
|
59 | var value = state.value;
|
60 | var ok = state.state === FULFILLED;
|
61 | var handler = ok ? reaction.ok : reaction.fail;
|
62 | var resolve = reaction.resolve;
|
63 | var reject = reaction.reject;
|
64 | var domain = reaction.domain;
|
65 | var result, then, exited;
|
66 | try {
|
67 | if (handler) {
|
68 | if (!ok) {
|
69 | if (state.rejection === UNHANDLED) onHandleUnhandled(state);
|
70 | state.rejection = HANDLED;
|
71 | }
|
72 | if (handler === true) result = value;
|
73 | else {
|
74 | if (domain) domain.enter();
|
75 | result = handler(value);
|
76 | if (domain) {
|
77 | domain.exit();
|
78 | exited = true;
|
79 | }
|
80 | }
|
81 | if (result === reaction.promise) {
|
82 | reject(new TypeError('Promise-chain cycle'));
|
83 | } else if (then = isThenable(result)) {
|
84 | call(then, result, resolve, reject);
|
85 | } else resolve(result);
|
86 | } else reject(value);
|
87 | } catch (error) {
|
88 | if (domain && !exited) domain.exit();
|
89 | reject(error);
|
90 | }
|
91 | };
|
92 |
|
93 | var notify = function (state, isReject) {
|
94 | if (state.notified) return;
|
95 | state.notified = true;
|
96 | microtask(function () {
|
97 | var reactions = state.reactions;
|
98 | var reaction;
|
99 | while (reaction = reactions.get()) {
|
100 | callReaction(reaction, state);
|
101 | }
|
102 | state.notified = false;
|
103 | if (isReject && !state.rejection) onUnhandled(state);
|
104 | });
|
105 | };
|
106 |
|
107 | var dispatchEvent = function (name, promise, reason) {
|
108 | var event, handler;
|
109 | if (DISPATCH_EVENT) {
|
110 | event = document.createEvent('Event');
|
111 | event.promise = promise;
|
112 | event.reason = reason;
|
113 | event.initEvent(name, false, true);
|
114 | global.dispatchEvent(event);
|
115 | } else event = { promise: promise, reason: reason };
|
116 | if (!NATIVE_PROMISE_REJECTION_EVENT && (handler = global['on' + name])) handler(event);
|
117 | else if (name === UNHANDLED_REJECTION) hostReportErrors('Unhandled promise rejection', reason);
|
118 | };
|
119 |
|
120 | var onUnhandled = function (state) {
|
121 | call(task, global, function () {
|
122 | var promise = state.facade;
|
123 | var value = state.value;
|
124 | var IS_UNHANDLED = isUnhandled(state);
|
125 | var result;
|
126 | if (IS_UNHANDLED) {
|
127 | result = perform(function () {
|
128 | if (IS_NODE) {
|
129 | process.emit('unhandledRejection', value, promise);
|
130 | } else dispatchEvent(UNHANDLED_REJECTION, promise, value);
|
131 | });
|
132 |
|
133 | state.rejection = IS_NODE || isUnhandled(state) ? UNHANDLED : HANDLED;
|
134 | if (result.error) throw result.value;
|
135 | }
|
136 | });
|
137 | };
|
138 |
|
139 | var isUnhandled = function (state) {
|
140 | return state.rejection !== HANDLED && !state.parent;
|
141 | };
|
142 |
|
143 | var onHandleUnhandled = function (state) {
|
144 | call(task, global, function () {
|
145 | var promise = state.facade;
|
146 | if (IS_NODE) {
|
147 | process.emit('rejectionHandled', promise);
|
148 | } else dispatchEvent(REJECTION_HANDLED, promise, state.value);
|
149 | });
|
150 | };
|
151 |
|
152 | var bind = function (fn, state, unwrap) {
|
153 | return function (value) {
|
154 | fn(state, value, unwrap);
|
155 | };
|
156 | };
|
157 |
|
158 | var internalReject = function (state, value, unwrap) {
|
159 | if (state.done) return;
|
160 | state.done = true;
|
161 | if (unwrap) state = unwrap;
|
162 | state.value = value;
|
163 | state.state = REJECTED;
|
164 | notify(state, true);
|
165 | };
|
166 |
|
167 | var internalResolve = function (state, value, unwrap) {
|
168 | if (state.done) return;
|
169 | state.done = true;
|
170 | if (unwrap) state = unwrap;
|
171 | try {
|
172 | if (state.facade === value) throw new TypeError("Promise can't be resolved itself");
|
173 | var then = isThenable(value);
|
174 | if (then) {
|
175 | microtask(function () {
|
176 | var wrapper = { done: false };
|
177 | try {
|
178 | call(then, value,
|
179 | bind(internalResolve, wrapper, state),
|
180 | bind(internalReject, wrapper, state)
|
181 | );
|
182 | } catch (error) {
|
183 | internalReject(wrapper, error, state);
|
184 | }
|
185 | });
|
186 | } else {
|
187 | state.value = value;
|
188 | state.state = FULFILLED;
|
189 | notify(state, false);
|
190 | }
|
191 | } catch (error) {
|
192 | internalReject({ done: false }, error, state);
|
193 | }
|
194 | };
|
195 |
|
196 |
|
197 | if (FORCED_PROMISE_CONSTRUCTOR) {
|
198 |
|
199 | PromiseConstructor = function Promise(executor) {
|
200 | anInstance(this, PromisePrototype);
|
201 | aCallable(executor);
|
202 | call(Internal, this);
|
203 | var state = getInternalPromiseState(this);
|
204 | try {
|
205 | executor(bind(internalResolve, state), bind(internalReject, state));
|
206 | } catch (error) {
|
207 | internalReject(state, error);
|
208 | }
|
209 | };
|
210 |
|
211 | PromisePrototype = PromiseConstructor.prototype;
|
212 |
|
213 |
|
214 | Internal = function Promise(executor) {
|
215 | setInternalState(this, {
|
216 | type: PROMISE,
|
217 | done: false,
|
218 | notified: false,
|
219 | parent: false,
|
220 | reactions: new Queue(),
|
221 | rejection: false,
|
222 | state: PENDING,
|
223 | value: undefined
|
224 | });
|
225 | };
|
226 |
|
227 |
|
228 |
|
229 | Internal.prototype = defineBuiltIn(PromisePrototype, 'then', function then(onFulfilled, onRejected) {
|
230 | var state = getInternalPromiseState(this);
|
231 | var reaction = newPromiseCapability(speciesConstructor(this, PromiseConstructor));
|
232 | state.parent = true;
|
233 | reaction.ok = isCallable(onFulfilled) ? onFulfilled : true;
|
234 | reaction.fail = isCallable(onRejected) && onRejected;
|
235 | reaction.domain = IS_NODE ? process.domain : undefined;
|
236 | if (state.state === PENDING) state.reactions.add(reaction);
|
237 | else microtask(function () {
|
238 | callReaction(reaction, state);
|
239 | });
|
240 | return reaction.promise;
|
241 | });
|
242 |
|
243 | OwnPromiseCapability = function () {
|
244 | var promise = new Internal();
|
245 | var state = getInternalPromiseState(promise);
|
246 | this.promise = promise;
|
247 | this.resolve = bind(internalResolve, state);
|
248 | this.reject = bind(internalReject, state);
|
249 | };
|
250 |
|
251 | newPromiseCapabilityModule.f = newPromiseCapability = function (C) {
|
252 | return C === PromiseConstructor || C === PromiseWrapper
|
253 | ? new OwnPromiseCapability(C)
|
254 | : newGenericPromiseCapability(C);
|
255 | };
|
256 |
|
257 | if (!IS_PURE && isCallable(NativePromiseConstructor) && NativePromisePrototype !== Object.prototype) {
|
258 | nativeThen = NativePromisePrototype.then;
|
259 |
|
260 | if (!NATIVE_PROMISE_SUBCLASSING) {
|
261 |
|
262 | defineBuiltIn(NativePromisePrototype, 'then', function then(onFulfilled, onRejected) {
|
263 | var that = this;
|
264 | return new PromiseConstructor(function (resolve, reject) {
|
265 | call(nativeThen, that, resolve, reject);
|
266 | }).then(onFulfilled, onRejected);
|
267 |
|
268 | }, { unsafe: true });
|
269 | }
|
270 |
|
271 |
|
272 | try {
|
273 | delete NativePromisePrototype.constructor;
|
274 | } catch (error) { }
|
275 |
|
276 |
|
277 | if (setPrototypeOf) {
|
278 | setPrototypeOf(NativePromisePrototype, PromisePrototype);
|
279 | }
|
280 | }
|
281 | }
|
282 |
|
283 | $({ global: true, constructor: true, wrap: true, forced: FORCED_PROMISE_CONSTRUCTOR }, {
|
284 | Promise: PromiseConstructor
|
285 | });
|
286 |
|
287 | setToStringTag(PromiseConstructor, PROMISE, false, true);
|
288 | setSpecies(PROMISE);
|