2021-06-08

function Promise(executor) {

  this.PromiseState = 'pending' // promise状态

  this.PromiseResult = null // promise结果

  this.callbacks = [] // promise实例可以多次使用.then获取结果

  // resolve和reject的入参,分别传给了.then中的回调onResolved和onRejected

  const resolve = (data) => {

    if (this.PromiseState !== 'pending') return // promise状态只可以修改一次

    this.PromiseState = 'fulfilled'

    this.PromiseResult = data

    setTimeout(() => {// then是异步执行的,微任务,所以用setTimeout包裹起来

      this.callbacks.forEach((item) => {

        item.onResolved(data)

      })

    })

  }

  const reject = (data) => {

    if (this.PromiseState !== 'pending') return

    this.PromiseState = 'rejected'

    this.PromiseResult = data

    setTimeout(() => {

      this.callbacks.forEach((item) => {

        item.onRejected(data)

      })

    })

  }

  try {

    executor(resolve, reject) // executor立即执行,因为promise内的代码是同步执行的

  } catch (err) {

    reject(err)

  }

}

// 调用.then方法时会根据promise实例状态,决定执行哪一步操作

Promise.prototype.then = function (onResolved, onRejected) {

  // 判断回调函数参数,.catch异常穿透

  if (typeof onResolved !== 'function') {

    onResolved = (value) => value

  }

  if (typeof onRejected !== 'function') {

    onRejected = (err) => {

      throw err

    }

  }

  return new Promise((resolve, reject) => {

    // 封装一个callback方法,处理.then返回值的三种情况

    function callback(type) {

      try {

        // try catch处理.then返回第二种结果

        const res = type(this.PromiseResult)

        if (res instanceof Promise) {

          // 处理.then返回第三种结果

          res.then(

            (r) => {

              resolve(r)

            },

            (e) => {

              reject(e)

            }

          )

        } else {

          // 处理.then返回第一种结果

          resolve(res)

        }

      } catch (err) {

        reject(err)

      }

    }

    if (this.PromiseState === 'fulfilled') {

      // then是异步执行的,微任务,所以用setTimeout包裹起来

      setTimeout(() => {

        callback(onResolved)

      })

    }

    if (this.PromiseState === 'rejected') {

      setTimeout(() => {

        callback(onRejected)

      })

    }

    // 处理异步行为,先将异步操作存储起来,待执行resolve或reject时在调用异步操作

    if (this.PromiseState === 'pending') {

      this.callbacks.push({

        onResolved: () => callback(onResolved),

        onRejected: () => callback(onRejected),

      })

    }

  })

}

Promise.prototype.catch = function (onRejected) {

  return this.then(undefined, onRejected) // catch返回的表现和.then一样,所以这里复用.then

}

Promise.resolve = function (data) {

  return new Promise((resolve, reject) => {

    if (data instanceof Promise) {

      data.then(

        (r) => {

          resolve(data)

        },

        (e) => {

          reject(data)

        }

      )

    } else {

      resolve(data)

    }

  })

}

Promise.reject = function (data) {

  return new Promise((resolve, reject) => {

    reject(data)

  })

}

Promise.all = function (promises) {

  return new Promise((resolve, reject) => {

    let count = 0 // 创建一个变量用来记录promise是成功状态的数量

    let arr = [] // 创建一个数组用来接受返回结果

    for (let i = 0; i < promises.length; i++) {

      promises[i].then(

        (res) => {

          count++

          arr[i] = res // 这里不能直接push,因为异步请求的顺序不确定,所以通过索引固定返回结果顺序

          if (count === promises.length) {

            // 只有所有的都是成功,结果才是成功

            resolve(arr)

          }

        },

        (err) => {

          reject(err) // 有一个失败,结果就是失败

        }

      )

    }

  })

}

Promise.race = function (promises) {

  return new Promise((resolve, reject) => {

    for (let i = 0; i < promises.length; i++) {

      promises[i].then(

        (res) => {

          resolve(res) // 有一个成功,结果就是成功

        },

        (err) => {

          reject(err) // 有一个失败,结果就是失败

        }

      )

    }

  })

}

你可能感兴趣的:(2021-06-08)