const PENDING = 'PENDING'
const FULLFILLED = 'FULLFILLED'
const REJECTED = 'REJECTED'
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e)
}
}
resolve(value) {
if (this.status === PENDING) return;
this.status = FULLFILLED;
this.value = value;
while (this.onFulfilledCallbacks.length) {
this.onFulfilledCallbacks.shift()(this.PromiseResult)
}
}
reject(reason) {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.onRejectedCallbacks.length) {
this.onRejectedCallbacks.shift()(this.PromiseResult)
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
if (this.status === 'fulfilled') {
onFulfilled(this.PromiseResult);
} else if (this.status === 'rejected') {
onRejected(this.PromiseResult);
} else if (this.status === 'pending') {
this.onFulfilledCallbacks.push(onFulfilled.bind(this))
this.onRejectedCallbacks.push(onRejected.bind(this))
}
}
}