1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| class MyPromise { constructor(executor) { this.state = 'pending' this.value = undefined this.reason = undefined this.onFulfilledCallbacks = [] this.onRejectedCallbacks = []
const resolve = (value) => { if (this.state !== 'pending') return this.state = 'fulfilled' this.value = value this.onFulfilledCallbacks.forEach(fn => fn()) }
const reject = (reason) => { if (this.state !== 'pending') return this.state = 'rejected' this.reason = reason this.onRejectedCallbacks.forEach(fn => fn()) }
try { executor(resolve, reject) } catch (error) { reject(error) } }
then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
const promise2 = new MyPromise((resolve, reject) => { if (this.state === 'fulfilled') { queueMicrotask(() => { try { const x = onFulfilled(this.value) resolvePromise(promise2, x, resolve, reject) } catch (error) { reject(error) } }) }
if (this.state === 'rejected') { queueMicrotask(() => { try { const x = onRejected(this.reason) resolvePromise(promise2, x, resolve, reject) } catch (error) { reject(error) } }) }
if (this.state === 'pending') { this.onFulfilledCallbacks.push(() => { queueMicrotask(() => { try { const x = onFulfilled(this.value) resolvePromise(promise2, x, resolve, reject) } catch (error) { reject(error) } }) })
this.onRejectedCallbacks.push(() => { queueMicrotask(() => { try { const x = onRejected(this.reason) resolvePromise(promise2, x, resolve, reject) } catch (error) { reject(error) } }) }) } })
return promise2 }
catch(onRejected) { return this.then(null, onRejected) }
static resolve(value) { return new MyPromise(resolve => resolve(value)) }
static reject(reason) { return new MyPromise((_, reject) => reject(reason)) } }
function resolvePromise(promise2, x, resolve, reject) { if (promise2 === x) { return reject(new TypeError('Chaining cycle detected')) }
if (x instanceof MyPromise) { x.then(resolve, reject) } else { resolve(x) } }
|