这一版在class中创建了一个callback,用于接收then方法中传入的回调函数,由于这个回调函数需要将class中的#result传入,而如果实例中的resolve是异步执行的,那么这个传入的回调函数无法立即获得resolve传进来的值,所以要使用一个变量接收这个方法,然后在#resolve或者#reject中调用
另外then方法是将任务放到了微任务队列中,所以我们需要使用queueMicrotask这个方法。
上述解释如果看不明白,可以看一看我的上篇文章哦封装一个简陋的promise
这一版是解决异步操作的问题,但是链式操作还没有解决
class myPromise {
// #相当于private,能让属性或者方法称为私有属性或者方法,只能在class中使用,实例无法使用,
// 状态、结果、以及resolve和reject我们只希望在class中使用、修改,不能通过实例直接修改,所以要变成私有的
#state = 0; // 0为pending 1为fulfilled 2为rejected
#result; // 存放resolve或者reject传过来的值
#callback; // 存放回调函数
constructor(executor) { // 构造器,在创建实例时,会自动调用这个函数
executor(this.#resolve.bind(this), this.#reject.bind(this))
// executor是创建实例时传进来的回调函数,我们要在实例创建时就调用
// executor中又传入了两个参数,分别是resolve和reject,分别要成功或者失败的值储存起来
}
#resolve(value) {
// 当resolve执行时,代表值已经传进来了,
// 这里的value是创建实例时resolve传过来的值
if (this.#state !== 0) return;
this.#result = value;
this.#state = 1; // 状态为fulfilled
// 解决异步执行问题
queueMicrotask(() => { // 将任务放到微任务队列中
this.#callback && this.#callback(this.#result); // 当callback有值时,就执行
})
}
#reject(reason) {
// 这里的reason是创建实例时reject传过来的值
if (this.#state !== 0) return;
this.#result = reason;
this.#state = 2; // 状态为rejected
// 解决异步执行问题
queueMicrotask(() => { // 将任务放到微任务队列中
this.#callback && this.#callback(this.#result); // 当callback有值时,就执行
})
}
then(onFullfilled, onRejected) { // then方法里面接收两个参数,一个是成功时执行的代码,一个是失败时执行的代码
if (this.#state === 0) { // 此时this.#result还没有值,需要将回调函数传给callback,由#resolve代为执行
this.#callback = onFullfilled
}
else if (this.#state === 1) {
onFullfilled(this.#result);
}
else if (this.#state === 2 && onRejected) {
onRejected(this.#result);
}
}
catch(onRejected) { // catch方法里接收一个参数,是失败时执行的代码
if (this.#state === 0) {
this.#callback = onRejected
}
else if (this.#state === 2 && onRejected) {
onRejected(this.#result);
}
}
}
let promise = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve("异步执行")
}, 1000);
})
promise.then(res => {
console.log(res);
})