美文网首页
promise实现

promise实现

作者: storyWrite | 来源:发表于2021-12-04 11:26 被阅读0次
    /*
     * @Author: dezhao.zhao@hand-china.com
     * @Date: 2021-11-23 15:37:06
     * @Description:
     */
    // 定义状态常量
    const PENDING = 'pending',
      FULFILLED = 'fulfilled',
      REJECTE = 'reject'
    function MyPromise(executor) {
      const self = this // 缓存promise对象
      // 初始执行 状态为pending
      self.status = PENDING
      // 成功回调
      self.onResolveCb = []
      // 失败回调
      self.onRejectedCb = []
      // 成功执行函数
      function resolve(value) {
        // 如果promise 返回值为一个promise 则执行zhen 方法并传入resolve与reject函数
        if (value instanceof MyPromise) {
          return value.then(resolve, reject)
        }
        // 只有等待态调用该函数,状态才会转为成功态
        if (self.status === PENDING) {
          self.status = FULFILLED
          // 成功后获得值,不可修改
          self.value = value
          // 调用所有成功回调
          self.onResolveCb.forEach((cb) => cb(value))
        }
      }
      function reject(reason) {
        // 只有等待态调用该函数,状态转为失败态
        if (self.status === PENDING) {
          self.status = REJECTE
          // 失败后获得值,不可修改
          self.value = reason
          // 调用所有失败回调
          self.onRejectedCb.forEach((cb) => cb(reason))
        }
      }
      try {
        // 函数执行可能报错,报错则需要reject
        executor(resolve, reject)
      } catch (e) {
        reject(e)
      }
    }
    
    MyPromise.prototype.then = function (onFulFilled, onRejected) {
      // 如果没有传成功回调函数,则赋值一个默认函数
      onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : (value) => value
      onRejected =
        typeof onRejected === 'function'
          ? onRejected
          : (reason) => {
              throw new e(reason)
            }
    
      let self = this
      let promise2
      if (self.status === FULFILLED) {
        console.log('then fulfilled')
        return (promise2 = new MyPromise((resolve, reject) => {
          // 所有成功与失败设置为异步,下一个事件循环执行,保证用户excutor中的代码先执行完成然后再执行onFulfilled回调
          setTimeout(() => {
            try {
              let x = onFulFilled(self.value)
              // 解析then中返回的promise
              resolvePromise(promise2, x, resolve, reject)
            } catch (e) {
              reject(e)
            }
          })
        }))
      }
      if (self.status === REJECTE) {
        promise2 = new MyPromise((resolve, reject) => {
          setTimeout(() => {
            try {
              let x = onRejected(self.value)
              resolvePromise(promise2, x, resolve, reject)
            } catch (e) {
              reject(e)
            }
          })
        })
        return promise2
      }
      if (self.status === PENDING) {
        console.log('then pending')
        // pending状态添加成功回调
        self.onResolveCb.push(() => {
          return (promise2 = new MyPromise((resolve, reject) => {
            setTimeout(() => {
              try {
                let x = onFulFilled(self.value)
                resolvePromise(promise2, x, resolve, reject)
              } catch (e) {
                reject(e)
              }
            })
          }))
        })
        // pending状态添加失败回调
        self.onRejectedCb.push(() => {
          return (promise2 = new MyPromise((resolve, reject) => {
            setTimeout(() => {
              try {
                let x = onRejected(self.value)
                resolvePromise(promise2, x, resolve, reject)
              } catch (e) {
                reject(e)
              }
            })
          }))
        })
      }
    }
    
    function resolvePromise(promise2, x, resolve, reject) {
      // let p2 = p1.then(() => p2)
      console.log('resolve Promise')
      let called = false
      if (promise2 === x) {
        return reject(new Typee('循环引用'))
      }
      if (x instanceof MyPromise) {
        if (x.status === PENDING) {
          x.then(function (y) {
            resolvePromise(promise2, y, resolve, reject)
          }, reject)
        } else {
          x.then(resolve, reject)
        }
        // thenable Object 有then方法的对象或者方法
      } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
        // 当then为get属性的时候,可以设置抛出异常
        try {
          console.log('应该执行到这里', typeof x.then === 'function')
    
          let then = x.then
          if (typeof then === 'function') {
            then.call(
              function () {
                console.log('执行到here')
    
                if (called) return
                called = true
                resolvePromise(promise2, x, resolve, reject)
              },
              function (e) {
                if (called) return
                called = true
                reject(e)
              }
            )
          } else {
            // 到此表示x.then 不存在 或者不是一个函数
            resolve(x)
          }
        } catch (e) {}
        // 字符串或其他基本数据
      } else {
        if (called) return
        called = true
        resolve(x)
      }
    }
    MyPromise.prototype.catch = function (onRejected) {
      this.then(null, onRejected)
    }
    
    MyPromise.deferred = MyPromise.defer = function () {
      let defer = {}
      defer.promise = new MyPromise(function (resolve, reject) {
        defer.resolve = resolve
        defer.reject = reject
      })
      return defer
    }
    MyPromise.all = function (promises) {
      return new MyPromise((resolve, reject) => {
        const result = []
        // count 不能定义在done里面 不然每次都会初始化为0,计数错误
        let count = 0
        function done(index) {
          return function (data) {
            result[index] = data
            if (++count === promises.length) {
              resolve(result)
            }
          }
        }
        promises.forEach((promise, index) => {
          promise.then(done(index), reject)
        })
      })
    }
    MyPromise.race = function (promises) {
      return new MyPromise((resolve, reject) => {
        promises.forEach((promises) => {
          promises.then(resolve, reject)
        })
      })
    }
    MyPromise.resolve = function (value) {
      return new MyPromise((resolve) => resolve(value))
    }
    MyPromise.reject = function (reason) {
      return new MyPromise(resolve, (reject) => reject(reason))
    }
    /**
     * 2
     */
    // const ps = [
    //   new MyPromise((resolve, reject) => {
    //     resolve(122)
    //     setTimeout(() => {
    //       reject(1)
    //     }, 1000)
    //   }),
    //   new MyPromise((resolve, reject) => {
    //     setTimeout(() => {
    //       resolve(2)
    //     }, 1000)
    //   })
    // ]
    // const p1 = MyPromise.race(ps).then(
    //   (data) => {
    //     console.log('data', data)
    //   },
    //   (err) => {
    //     console.log('err', err)
    //   }
    // )
    /**
     * 1.
     */
    // const p1 = new MyPromise((resolve, reject) => {
    //   const num = Math.random()
    //   if (num > 0.5) {
    //     console.log('222')
    //     resolve(23323)
    //     setTimeout(() => {
    //       resolve(num)
    //     }, 1000)
    //   } else {
    //     reject(num)
    //   }
    // })
    // // const p2 = p1.then();
    // let p2 = p1.then(
    //   (data) => {
    //     console.log('data', data)
    
    //     // return p2
    //   },
    //   (err) => {
    //     console.log('err', err)
    //     // return p2
    //   }
    // )
    // p2.then(
    //   (data) => {
    //     console.log('p2 data', data)
    //   },
    //   (err) => {
    //     console.log('p2 err', err)
    //   }
    // )
    
    const pr1 = new MyPromise((resolve) => {
      resolve(100)
    })
    const pr2 = pr1.then((data) => {
      console.log('datapro1', data)
    
      return new Promise((resolve) => {
        resolve(data)
      })
    })
    pr2.then((data) => console.log('datapro2', data))
    
    

    相关文章

      网友评论

          本文标题:promise实现

          本文链接:https://www.haomeiwen.com/subject/ffpixrtx.html