极简版Promise

506 阅读1分钟

前言

极简版 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 了。 当然这些细节 基于观察者模式,我们还是很容易补齐的,文中主要讲设计思想。

参考

  1. es6-promise