17 | 17 |
const FULFILLED = 1;
|
18 | 18 |
const REJECTED = 2;
|
19 | 19 |
|
20 | |
const TRY_CATCH_ERROR = { error: null };
|
21 | |
|
22 | 20 |
function selfFulfillment() {
|
23 | 21 |
return new TypeError("You cannot resolve a promise with itself");
|
24 | 22 |
}
|
25 | 23 |
|
26 | 24 |
function cannotReturnOwn() {
|
27 | 25 |
return new TypeError('A promises callback cannot return that same promise.');
|
28 | |
}
|
29 | |
|
30 | |
function getThen(promise) {
|
31 | |
try {
|
32 | |
return promise.then;
|
33 | |
} catch(error) {
|
34 | |
TRY_CATCH_ERROR.error = error;
|
35 | |
return TRY_CATCH_ERROR;
|
36 | |
}
|
37 | 26 |
}
|
38 | 27 |
|
39 | 28 |
function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
|
|
46 | 35 |
|
47 | 36 |
function handleForeignThenable(promise, thenable, then) {
|
48 | 37 |
asap(promise => {
|
49 | |
var sealed = false;
|
50 | |
var error = tryThen(then, thenable, value => {
|
|
38 |
let sealed = false;
|
|
39 |
let error = tryThen(then, thenable, value => {
|
51 | 40 |
if (sealed) { return; }
|
52 | 41 |
sealed = true;
|
53 | 42 |
if (thenable !== value) {
|
|
86 | 75 |
maybeThenable.constructor.resolve === originalResolve) {
|
87 | 76 |
handleOwnThenable(promise, maybeThenable);
|
88 | 77 |
} else {
|
89 | |
if (then === TRY_CATCH_ERROR) {
|
90 | |
reject(promise, TRY_CATCH_ERROR.error);
|
91 | |
TRY_CATCH_ERROR.error = null;
|
92 | |
} else if (then === undefined) {
|
|
78 |
if (then === undefined) {
|
93 | 79 |
fulfill(promise, maybeThenable);
|
94 | 80 |
} else if (isFunction(then)) {
|
95 | 81 |
handleForeignThenable(promise, maybeThenable, then);
|
|
103 | 89 |
if (promise === value) {
|
104 | 90 |
reject(promise, selfFulfillment());
|
105 | 91 |
} else if (objectOrFunction(value)) {
|
106 | |
handleMaybeThenable(promise, value, getThen(value));
|
|
92 |
let then;
|
|
93 |
try {
|
|
94 |
then = value.then;
|
|
95 |
} catch (error) {
|
|
96 |
reject(promise, error);
|
|
97 |
return;
|
|
98 |
}
|
|
99 |
handleMaybeThenable(promise, value, then);
|
107 | 100 |
} else {
|
108 | 101 |
fulfill(promise, value);
|
109 | 102 |
}
|
|
173 | 166 |
promise._subscribers.length = 0;
|
174 | 167 |
}
|
175 | 168 |
|
176 | |
|
177 | |
function tryCatch(callback, detail) {
|
178 | |
try {
|
179 | |
return callback(detail);
|
180 | |
} catch(e) {
|
181 | |
TRY_CATCH_ERROR.error = e;
|
182 | |
return TRY_CATCH_ERROR;
|
183 | |
}
|
184 | |
}
|
185 | |
|
186 | 169 |
function invokeCallback(settled, promise, callback, detail) {
|
187 | 170 |
let hasCallback = isFunction(callback),
|
188 | |
value, error, succeeded, failed;
|
|
171 |
value, error, succeeded = true;
|
189 | 172 |
|
190 | 173 |
if (hasCallback) {
|
191 | |
value = tryCatch(callback, detail);
|
192 | |
|
193 | |
if (value === TRY_CATCH_ERROR) {
|
194 | |
failed = true;
|
195 | |
error = value.error;
|
196 | |
value.error = null;
|
197 | |
} else {
|
198 | |
succeeded = true;
|
|
174 |
try {
|
|
175 |
value = callback(detail);
|
|
176 |
} catch (e) {
|
|
177 |
succeeded = false;
|
|
178 |
error = e;
|
199 | 179 |
}
|
200 | 180 |
|
201 | 181 |
if (promise === value) {
|
202 | 182 |
reject(promise, cannotReturnOwn());
|
203 | 183 |
return;
|
204 | 184 |
}
|
205 | |
|
206 | 185 |
} else {
|
207 | 186 |
value = detail;
|
208 | |
succeeded = true;
|
209 | 187 |
}
|
210 | 188 |
|
211 | 189 |
if (promise._state !== PENDING) {
|
212 | 190 |
// noop
|
213 | 191 |
} else if (hasCallback && succeeded) {
|
214 | 192 |
resolve(promise, value);
|
215 | |
} else if (failed) {
|
|
193 |
} else if (succeeded === false) {
|
216 | 194 |
reject(promise, error);
|
217 | 195 |
} else if (settled === FULFILLED) {
|
218 | 196 |
fulfill(promise, value);
|
|
248 | 226 |
export {
|
249 | 227 |
nextId,
|
250 | 228 |
makePromise,
|
251 | |
getThen,
|
252 | 229 |
noop,
|
253 | 230 |
resolve,
|
254 | 231 |
reject,
|