const PENDING = 'pending'const FULFILLED = 'fulfilled'const REJECTED = 'rejected'class Promise { constructor(executor) { this.state = PENDING this.value = null this.reason = null this.onFulfilledCallbacks = [] this.onRejectedCallbacks = [] const resolve = value => { setTimeout(() => { if (this.state === PENDING) { this.state = FULFILLED this.value = value this.onFulfilledCallbacks.forEach(cb => { cb = cb(this.value) }) } }); } const reject = reason => { setTimeout(() => { if (this.state === PENDING) { this.state = REJECTED this.reason = reason this.onRejectedCallbacks.forEach(cb => { cb = cb(this.reason) }) } }); } try { executor(resolve, reject) } catch (e) { reject(e) } } then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason } let newPromise if (this.state === FULFILLED) { return (newPromise = new Promise((resolve, reject) => { setTimeout(() => { try { let x = onFulfilled(this.value) resolvePromise(newPromise, x, resolve, reject) } catch (e) { reject(e) } }); })) } if (this.state === REJECTED) { return (newPromise = new Promise((resolve, reject) => { setTimeout(() => { try { let x = onRejected(this.reason) resolvePromise(newPromise, x, resolve, reject) } catch (e) { reject(e) } }); })) } if (this.state === PENDING) { return (newPromise = new Promise((resolve, reject) => { this.onFulfilledCallbacks.push(value => { try { let x = onFulfilled(value) resolvePromise(newPromise, x, resolve, reject) } catch (e) { reject(e) } }) this.onRejectedCallbacks.push(reason => { try { let x = onRejected(reason) resolvePromise(newPromise, x, resolve, reject) } catch (e) { reject(e) } }) })) } }}function resolvePromise(promise2, x, resolve, reject) { if (x === promise2) { reject(new TypeError()) } if (x instanceof Promise) { if (x.state === PENDING) { x.then(y => { resolvePromise(promise2, y, resolve, reject) }, reason => { reject(reason) }) } else { x.then(resolve, reject) } } else if (x && (typeof x === 'function' || typeof x === 'object')) { let called = false try { let then = x.then if (typeof then === 'function') { then.call(x, y => { if (called) return called = true resolvePromise(promise2, y, resolve, reject) }, r => { if (called) return called = true reject(r) }) } else { resolve(x) } } catch (e) { if (called) return called = true reject(e) } } else { resolve(x) }}