_promise
by liujilong
JavaScript
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
constructor(executor) {
try {
executor(this._resolve, this._reject)
} catch (e) {
this._reject(e)
}
}
state = PENDING
result = undefined
reason = ''
fulfilledCallbacks = []
rejectedCallbacks = []
_resolve = value => {
if (this.state !== PENDING) return
this.state = FULFILLED
this.result = value
this.fulfilledCallbacks.forEach(cb => cb())
}
_reject = reason => {
if (this.state !== PENDING) return
this.state = REJECTED
this.reason = reason
this.rejectedCallbacks.forEach(cb => cb())
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
const self = this
const promise2 = new MyPromise((resolve, reject) => {
if (self.state === FULFILLED) {
setTimeout(() => {
try {
const res = onFulfilled(self.result)
self._resolvePromise(promise2, res, resolve, reject)
} catch (e) {
reject(e)
}
})
} else if (self.state === REJECTED) {
setTimeout(() => {
try {
const x = onRejected(self.reason)
self._resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
} else if (self.state === PENDING) {
self.fulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const res = onFulfilled(self.result)
self._resolvePromise(promise2, res, resolve, reject)
} catch (e) {
reject(e)
}
})
})
self.rejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(self.reason)
...