const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
#state = PENDING // 私有属性
#result = undefined
#handlers = []
constructor(executor) {
const resolve = (data) => {
this.#changeState(FULFILLED, data)
}
const reject = (reason) => {
this.#changeState(REJECTED, reason)
}
try {
executor(resolve, reject)
} catch (err) {
// 只能捕获同步错误
reject(err)
}
}
#changeState(state, result) {
if (this.#state !== PENDING) return
this.#state = state
this.#result = result
this.#run()
}
#runMicroTask(func) {
if (typeof process === 'object' && typeof process.nextTick === 'function') {
process.nextTick(func)
} else if (typeof MutationObserver === 'function') {
const ob = new MutationObserver(func)
const textNode = document.createTextNode('1')
ob.observe(textNode, {
characterData: true,
})
textNode.data = 2
} else {
setTimeout(func, 0)
}
}
#isPromiseLike(value) {
if (value !== null && (typeof value === 'object' || typeof value === 'function')) {
return typeof value.then === 'function'
}
return false
}
#runOne(callback, resolve, reject) {
this.#runMicroTask(() => {
if (typeof callback !== 'function') {
const settled = this.#state === FULFILLED ? resolve : reject
settled(this.#result)
}
try {
const data = callback(this.#result)
if (this.#isPromiseLike(data)) {
data.then(resolve, reject)
} else {
resolve(data)
}
} catch (err) {
reject(err)
}
})
}
#run() {
if (this.#state === PENDING) return
while (this.#handlers.length) {
// shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值
const { onFulfilled, onRejected, resolve, reject } = this.#handlers.shift()
if (this.#state === FULFILLED) {
this.#runOne(onFulfilled, resolve, reject)
} else {
this.#runOne(onRejected, resolve, reject)
}
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
this.#handlers.push({
onFulfilled,
onRejected,
resolve,
reject,
})
this.#run()
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
finally(onFinally) {
return this.then(
(data) => {
onFinally()
return data
},
(reason) => {
onFinally()
throw err
}
)
}
static resolve(value) {
if (value instanceof MyPromise) return value
let _resolve, _reject
const p = new MyPromise((resolve, reject) => {
_resolve = resolve
_reject = reject
})
if (p.#isPromiseLike(value)) {
value.then(_resolve, _reject)
} else {
_resolve(value)
}
}
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
}
10. 手写Promise
最新推荐文章于 2024-07-12 16:55:56 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)