手写 promise 实现then,catch,finally等
const promiseStatus = {
PENDING: 'pending',
FULFILLED: 'fulfilled',
REJECTED: 'rejected',
}
class myPromise {
constructor(executor) {
this.status = promiseStatus.PENDING
this.value = undefined
this.error = undefined
this.resfns = []
this.errfns = []
const resolve = (value) => {
if (this.status === promiseStatus.PENDING) {
queueMicrotask(() => {
if (this.status !== promiseStatus.PENDING) return
this.status = promiseStatus.FULFILLED
this.value = value
this.resfns.forEach((fn) => {
fn(this.value)
})
})
}
}
const reject = (error) => {
if (this.status === promiseStatus.PENDING) {
queueMicrotask(() => {
if (this.status !== promiseStatus.PENDING) return
this.status = promiseStatus.REJECTED
this.error = error
this.errfns.forEach((fn) => {
fn(this.error)
})
})
}
}
executor(resolve, reject)
}
// then 方法
then(resfn, errfn) {
return new myPromise((resolve, reject) => {
if (this.status === promiseStatus.FULFILLED && resfn) {
try {
const value = resfn(this.value)
resolve(value)
} catch (err) {
reject(err)
}
}
if (this.status === promiseStatus.REJECTED && errfn) {
try {
const value = errfn(this.error)
resolve(value)
} catch (err) {
reject(err)
}
}
if (this.status === promiseStatus.PENDING) {
this.resfns.push(() => {
try {
const value = resfn(this.value)
resolve(value)
} catch (err) {
reject(err)
}
})
this.errfns.push(() => {
try {
const value = errfn(this.error)
resolve(value)
} catch (err) {
reject(err)
}
})
}
})
}
// catch 方法
catch(errfn) {
return this.then(undefined, errfn)
}
// finally 方法
finally(onFinally) {
return this.then(() => onFinally(),() => onFinally());
}
// 其余方法就省略了
}
测试:
const p1 = new MyPromise((resolve, reject) => {
setTimeout(() => {
console.log("--- 1 ---");
resolve(111);
});
}).then(res => {
console.log("p1 res :>> ", res);
});const p2 = new MyPromise((resolve, reject) => {
console.log("--- 2 ---");
resolve(222);
});
const p3 = new MyPromise((resolve, reject) => {
console.log("--- 3 ---");
resolve(333);
});
const p3 = new MyPromise((resolve, reject) => {
console.log("--- 3 ---");
resolve(333);
});
const p4 = new MyPromise((resolve, reject) => {
console.log("--- 4 ---");
reject(444);
});
MyPromise.all([p2, p3]).then(res => {
console.log("p2&p3 res :>> ", res);
});MyPromise.all([p2, p4]).then(res => {
console.log("p2&p4 res :>> ", res);
}).catch(err => {
console.log("err :>> ", err);
});//输出结果
// --- 2 ---
// --- 3 ---
// --- 4 ---
// p2&p3 res :>> [ 222, 333 ]
// err :>> 444
// --- 1 ---
// p1 res :>> 111
参考文章: