前言
极简版 Promise 没有错误捕捉,没有unwrap 内部 Promise,文章主要讲的是基于观察者设计模式,如何设计一个简单版的 Promise,
直接上代码
function nextTick(fn) {//异步函数
setTimeout(fn)
}
function resolve(promise, value) {// 被观察者状态更新
if (promise.state) { return; }
promise.state = 'full'
promise.result = value
publish(promise)
}
function reject(promise, value) {// 被观察者状态更新
if (promise.state) { return; }
promise.state = 'reject'
promise.result = value
publish(promise)
}
function subscribe(parent, child, onFulfilled, onRejected) {// 观察者收集
parent.subject.push({
child,
onFulfilled,
onRejected
})
}
function publish(promise) {// 通知观察者状态更新
if (promise.subject) {
nextTick(() => {
promise.subject.forEach((item) => {
if (promise.state === 'full') {
const childValue = item.onFulfilled(promise.result)
resolve(item.child, childValue)
} else {
const childValue = item.onFulfilled(promise.result)
resolve(item.child, childValue)
}
})
promise.subject = []
})
}
}
class Promise {
constructor(resolver) {
this.state = undefined;
this.result = undefined;
this.subject = [];
if (resolver) {
resolver((value) => {
resolve(this, value)
}, (err) => {
reject(this, err)
})
}
}
then(onFulfilled, onRejected) {// 观察者收集
const parent = this
const child = new Promise()
subscribe(parent, child, onFulfilled, onRejected)
if (parent.state) {
publish(parent)
}
return child
}
}
从上面的代码,我们很容易理解,promise 就是一个观察者兼顾被观察者一体,但是这个被观察者有点特殊,就是只会触发一次状态更新
状态流程图
stateDiagram-v2
[*] --> initPromise
initPromise --> childPromise1
initPromise --> childPromise2
childPromise1--> ...
childPromise2--> ....
总结
上面的代码除了 没有错误监控,没有unwrap,没有具体的微任务实现已经是一个合格的 Promise 了。 当然这些细节 基于观察者模式,我们还是很容易补齐的,文中主要讲设计思想。