可能还存在不完善的地方,有空再改改
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
//工具函数,捕获错误并转换为reject方法
const resolveOrCatchWithReject = (fn, val, resolve, reject) => {
try {
let value = fn(val)
resolve(value)
} catch (err) {
reject(err)
}
}
function isKanoPromise(x) { // 校验是否是 promise
if ((typeof x == 'object' && x !== null) || typeof x == 'function') {
if (typeof x.then == 'function') {
return true
}
}
return false
}
class KanoPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.resaon = undefined
this.onfulfilledFns = []
this.onrejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
queueMicrotask(() => { //微任务队列
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_FULFILLED
this.value = value
// 执行then传入的回调函数(第一个)
// console.log('resolve被调用');
this.onfulfilledFns.forEach(fn => {
// if(isKanoPromise(value)){
// value.then(res=>{
// return res
// })
// }
fn && fn(this.value)
})
})
}
}
const reject = (resaon) => {
if (this.status === PROMISE_STATUS_PENDING) {
queueMicrotask(() => { //微任务队列
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_REJECTED
this.resaon = resaon
// 执行then传入的回调函数(第二个)
// console.log('reject被调用');
this.onrejectedFns.forEach(fn => {
fn && fn(this.resaon)
})
});
}
}
try {
executor(resolve, reject)
} catch (err) {
reject(err)
}
}
then(onfulfilled, onrejected) {
//兼容catch托底方法(当then没有onrejected时)
const defaultOnRejected = errOrData => { throw errOrData }
onrejected = onrejected || defaultOnRejected
//没有onfulfilled时需要有一个默认的onfulfilled
const defaultOnFulfilled = value => { return value }
onfulfilled = onfulfilled || defaultOnFulfilled
//返回一个promise 实现then的链式调用
return new KanoPromise((resolve, reject) => {
//状态已敲定,不入队列,直接执行
if (this.status === PROMISE_STATUS_FULFILLED) {
resolveOrCatchWithReject(onfulfilled, this.value, resolve, reject)
}
//状态已敲定,不入队列,直接执行
if (this.status === PROMISE_STATUS_REJECTED) {
resolveOrCatchWithReject(onrejected, this.resaon, resolve, reject)
}
//状态未敲定,将回调置入回调执行队列中
if (this.status === PROMISE_STATUS_PENDING) {
//置入数组
this.onfulfilledFns.push(() => {
resolveOrCatchWithReject(onfulfilled, this.value, resolve, reject)
})
this.onrejectedFns.push(() => {
resolveOrCatchWithReject(onrejected, this.resaon, resolve, reject)
})
}
})
}
catch(onrejected) {
//执行then,reject动作由catch方法的onrejected回调函数托管
return this.then(undefined, onrejected)
}
finally(onfinally) {
//不管成功还是失败,都执行
return this.then(onfinally, onfinally)
}
static resolve(value) {
return new KanoPromise((resolve) => resolve(value))
}
static reject(reason) {
return new KanoPromise((_, reject) => reject(reason))
}
static all(promises) {
return new KanoPromise((resolve, reject) => {
const vals = []
promises.forEach(p => {
p.then(res => {
vals.push(res)
if (vals.length === promises.length) {
resolve(vals)
}
}, err => {
reject(err)
})
})
})
}
static allSettled(promises) {
return new KanoPromise((resolve) => {
const vals = []
promises.forEach(p => {
p.then(res => {
vals.push({ status: PROMISE_STATUS_FULFILLED, value: res })
if (vals.length === promises.length) {
resolve(vals)
}
}, err => {
vals.push({ status: PROMISE_STATUS_REJECTED, reason: err })
if (vals.length === promises.length) {
resolve(vals)
}
})
})
})
}
static race(promises) {
return new KanoPromise((resolve, reject) => {
promises.forEach(p => {
if (isKanoPromise(p)) {
p.then((res) => resolve(res), reject)
} else {
resolve(p)
}
})
})
}
static any(promises) {
const reasons = []
return new KanoPromise((resolve, reject) => {
promises.forEach(p => {
p.then(resolve, err => {
reasons.push(err)
if (reasons.length === promises.length) {
reject(new AggregateError(reasons))
}
})
})
})
}
`}`