JS - 手写promise

79 阅读1分钟

PromisesA+规范

任何符合promise规范的对象或函数都可以成为promise,promise A plus 规范地址: promisesaplus.com or zhuanlan.zhihu.com/p/353489929

Promise实现

   var Promise = function(handleFn) {
      this.thenFns = []
      this.catchFns = []
      this.status = 'pendding' // fulfilled rejected

      this.resolveValue = undefined
      this.rejectError = undefined

      setTimeout(() => {
        handleFn(this.resolve, this.reject)
      }, )
    }

    Promise.prototype.then = function(successCallBack, failCallBack) {
      // this.thenFns.push(thenFn)
      // return new Promise((resolve, reject) => {
      //   if (this.status === 'fulfilled') {
      //   }
      // })
      let promise2 = new Promise((resolve, reject) => {
        if (this.status === 'fulfilled') {
          let r = successCallBack(this.resolveValue)
          if (r === promise2) {
            return Promise.reject('Chaining cycle detected for promise #<Promise>')
          }

          if (r instanceof Promise) {
            x.then(resolve, reject)
          } else {
            resolve(x)
          }
        } else if (this.status === 'rejected') {
          failCallBack(this.rejectError)
        } else {
          this.thenFns.push(() => {
            setTimeout(() => {
              try {
                let x = successCallback(this.value)
                if (x instanceof Promise) {
                  x.then(resolve, reject)
                } else {
                  resolve(x)
                }
              } catch (e) {
                reject(e)
              }
            })
          })
          this.catchFns.push(failCallBack)
        }
      })
      return promise2
    }

  
    Promise.prototype.catch = function(catchFn) {
      this.catchFns.push(catchFn)
    }

    Promise.prototype.resolve = function(resolveValue) {
      if (this.status !== 'pendding') {
        return
      }
      this.status = 'fulfilled'
      this.resolveValue = resolveValue

      for (let i = 0; i < this.thenFns.length; ++i) {
        let thenResult = this.thenFns[i](resolveValue)
      }
    }

    Promise.prototype.reject = function(rejectError) {
      if (this.status !== 'pendding') {
        return
      }
      this.status = 'rejected'
      this.rejectError = rejectError

      for (let i = 0; i < this.catchFns.length; ++i) {
        let catchResult = this.catchFns[i](rejectError)
      }
    }