class MyPromise {
constructor(executor) {
this.initBind()
this.initValue()
try {
executor(this.resolve, this.reject)
} catch (err) {
this.reject(err)
}
}
initBind() {
// 初始化this
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}
initValue() {
this.PromiseState = 'pending'
this.PromiseResult = null
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
}
resolve(value) {
if (this.PromiseState !== 'pending') return
this.PromiseState = 'fulfilled'
this.PromiseResult = value
while (this.onFulfilledCallbacks.length) {
this.onFulfilledCallbacks.shift()(this.PromiseResult)
}
}
reject(err) {
if (this.PromiseState !== 'pending') return
this.PromiseState = 'rejected'
this.PromiseResult = err
while (this.onRejectedCallbacks.length) {
this.onRejectedCallbacks.shift()(this.PromiseResult)
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };
var thenPromise = new MyPromise((resolve, reject) => {
const resolvePromise = cb => {
try {
const x = cb(this.PromiseResult)
if (x instanceof MyPromise) {
x.then(resolve, reject)
} else {
resolve(x)
}
} catch(err) {
reject(err)
}
}
if (this.PromiseState === 'fulfilled') {
resolvePromise(onFulfilled)
} else if (this.PromiseState === 'rejected') {
resolvePromise(onRejected)
} else if (this.PromiseState === 'pending') {
this.onFulfilledCallbacks.push(onFulfilled.bind(this))
this.onRejectedCallbacks.push(onRejected.bind(this))
}
})
return thenPromise
}
}
var test = new MyPromise((resolve, reject) => {
console.log('construct')
resolve('hello')
// setTimeout(() => {
// resolve('hellow')
// }, 500)
// reject('hellow2')
// throw('3')
})
test.then((res) => {
console.log('first then: ', res)
return res + ' world'
}).then(res => {
console.log('sec then: ', res)
return new MyPromise((resolve, reject) => {
resolve(res + ', javascript')
}).then(res => {
console.log('then promise', res)
return res + ' then'
})
}).then(res => {
console.log('third then: ', res)
})
// console.log('test', test)
console