const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
function MyPromise(fn) {
const that = this //方便后面利用上下文,先把this赋值给that
this.state = PENDING // 初始状态为pending
this.value = null
this.resolvedCallbacks = [] // 这两个变量用于保存then中的回调,因为执行完Promise时状态可能还是pending
this.rejectedCallbacks = [] // 此时需要吧then中的回调保存起来方便状态改变时调用
function resolve(value) {
if(that.state === PENDING) {
that.state = RESOLVED // resolve函数执行时,若状态为pending,则把状态转换为resolved
that.value = value // 把值赋给this.value
that.resolvedCallbacks.map(cb => cb(value)) // 遍历数组,执行之前保存的then的回调函数
}
}
function reject(value) {
if(that.state === PENDING) { // 同上
that.state = REJECTED
that.value = value
that.rejectedCallbacks.map(cb => cb(value))
}
}
try{
fn(resolve, reject) // 尝试执行fn函数
} catch (err) {
reject(err) // 捕获错误
}
}
MyPromise.prototype.then = function(onFulfilled, onRejected) {
// 因为then的两个参数均为可选参数,
// 所以判断参数类型本身是否为函数,如果不是,则需要给一个默认函数如下(方便then不传参数时可以透传)
// 类似这样: Promise.resolve(4).then().then((value) => console.log(value))
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
onRejected = typeof onRejected === 'function' ? onRejected : err => {throw err}
if(this.state === PENDING) {
// 若执行then时仍为pending状态时,添加函数到对应的函数数组
this.resolvedCallbacks.push(onFulfilled)
this.rejectedCallbacks.push(onRejected)
}
if(this.state === RESOLVED) {
// resolved状态时,执行onFulfilled
onFulfilled(this.value)
}
if(this.state === REJECTED) {
// reject状态,执行onRejected
onRejected(this.value)
}
}
// 该例子就是:Promise执行完后,执行then函数时仍为pending状态,所以push函数进resolvedCallbacks后,才执行resolve函数
new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 0)
}).then(value => {
console.log(value)
})