promise实现

2021-12-04  本文已影响0人  storyWrite
/*
 * @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))

上一篇下一篇

猜你喜欢

热点阅读