根据PromiseA+规范实现一个Promise,js无法模拟微任务,通过setTimeout代替。
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'
class Promise {
constructor(executor) {
this.status = PENDING
this.result = undefined
this.callbacks = []
const resolve = value => {
if (this.status === PENDING) {
this.status = FULFILLED
this.result = value
setTimeout(() => {
this.callbacks.forEach(cb => {
cb.onResolved(value)
})
}, 0)
}
}
const reject = reason => {
if (this.status === PENDING) {
this.status = REJECTED
this.result = reason
setTimeout(() => {
this.callbacks.forEach(cb => {
cb.onRejected(reason)
})
}, 0)
}
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
then(onResolved, onRejected) {
onResolved = typeof onResolved === 'function' ? onResolved : value => value // 把 value 透传下去
onRejected =
typeof onRejected === 'function'
? onRejected
: reason => {
// 抛出错误 继续透传下去
throw reason
}
return new Promise((resolve, reject) => {
const handler = callback => {
try {
const value = callback(this.result)
// 如果返回值 value 是一个 Promise 的实例,则新Promise实例的状态由value的状态决定
if (value instanceof Promise) {
value.then(
res => resolve(res),
err => reject(err)
)
} else {
resolve(value)
}
} catch (e) {
reject(e)
}
}
// FULFILLED 和 FULFILLED 是针对 executor 是同步的情况
if (this.status === FULFILLED) {
setTimeout(() => {
handler(onResolved)
}, 0)
} else if (this.status === FULFILLED) {
setTimeout(() => {
handler(onRejected)
}, 0)
} else {
// PENDING
this.callbacks.push({
onResolved() {
handler(onResolved)
},
onRejected() {
handler(onRejected)
}
})
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
}
测试用例:
const p1 = new PromiseX((resolve, reject) => {
// resolve(2)
// throw new Error('oops')
reject('oops')
})
p1.then()
.then(res => {
console.log(res)
})
.catch()
.catch(err => {
console.log(err)
return new PromiseX(res => {
res('ok')
})
})
.then(res => {
console.log(res)
})
关于Promise的静态方法比如:Promise.all、Promise.race、Promise.allSettled等可以查看前端面试总结。






网友评论