Promise的特点:
执行了resolve,Promise状态会变成fulfilled;
执行了reject,Promise状态会变成rejected;
Promise状态不可逆,第一次成功就永久为fulfilled,第一次失败就永远状态为rejected;
Promise中有throw的话,就相当于执行了reject;
注意几个点我们依次去实现:
-
Promise的初始状态是pending;
-
需要对resolve和reject绑定this:确保resolve和reject的this指向永远指向当前的MyPromise实例,防止随着函数执行环境的改变而改变;
-
Promise中有throw的话,就相当于执行了reject。这就要使用try catch了
-
then方法,then接收两个回调,一个是成功回调,一个是失败回调;当Promise状态为fulfilled执行成功回调,为rejected执行失败回调;如resolve或reject在定时器里,则定时器结束后再执行then;then支持链式调用,下一次then执行受上一次then返回值的影响;
-
同时要注意执行顺序,promise回调属于微任务。
class MyPromise {
constructor(excutor) {
//初始化赋值
this.initValue()
try {
excutor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
}
initValue() {
this.promiseState = "pending"
this.promiseResult = null
//绑定到实例上
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
//准备一个事件队列
this.onFulfilledCallbacks = []
this.onRejectCalbacks = []
}
resolve(value) {
this.promiseState = "fulfilled"
this.promiseResult = value
while (this.onFulfilledCallbacks.length) {
this.onFulfilledCallbacks.shift()(this.promiseResult)
}
}
reject(reason) {
this.promiseState = "rejected"
this.promiseResult = reason
while (this.onRejectCalbacks.length) {
this.onRejectCalbacks.shift()(this.promiseResult)
}
}
then(onFulfilled, onReject) {
//判断为函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
onReject = typeof onReject === 'function' ? onReject : reason => { throw reason }
//保证then的返回是个promise对象,实现链式调用
const thenPromise = new MyPromise((resolve, reject) => {
const handlePromise = cb => {
//模拟异步任务
setTimeout(() => {
try {
const result = cb(this.promiseResult)
if (result === thenPromise) {
throw new Error('not self')
}
//如果是promise就调用链式.then,否则就抛出结果
if (result instanceof MyPromise) {
result.then(resolve, reject)
} else {
resolve(result)
}
} catch (error) {
reject(error)
throw new Error(error)
}
})
}
if (this.promiseState == 'fulfilled') {
// onFulfilled(this.promiseResult
handlePromise(onFulfilled)
} else if (this.promiseState == 'rejected') {
// onReject(this.promiseResult)
handlePromise(onReject)
} else {
//针对异步 使用队列存储 等执行到resolve或reject后再执行
// this.onFulfilledCallbacks.push(onFulfilled)
// this.onRejectCalbacks.push(onReject)
this.onFulfilledCallbacks.push(handlePromise(onFulfilled))
this.onRejectCalbacks.push(handlePromise(onFulfilled))
}
})
return thenPromise
}
}
new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(123)
}, 2000)
}).then(res => {
console.log(res);
})
console.log(1);