手写之Promise

105 阅读1分钟

手写Promise

class Prom {
  static resolve(value) {
    if (value && value.then) {
      return value
    }
    return new Prom(resolve => {
      resolve(value)
    })
  }

  constructor(fn) {
    this.value = ''
    this.reason = ''
    this.status = 'pending'
    /* 目的:为了处理异步 */
    this.resolvedFns = []
    this.rejectedFns = []

    const resolve = value => {
    /* 使用setTimeout能保证前面的模拟同步都执行完 */
      setTimeout(() => {
        this.status = 'resolved'
        this.value = value
        this.resolvedFns.forEach(({ fn, resolve: res, reject: rej }) => {
          res(fn(value))
        })
      })
    }

    const reject = reason => {
      setTimeout(() => {
        this.status = 'rejected'
        this.reason = reason
        this.rejectedFns.forEach(({ fn, resolve: res, reject: rej }) => {
          rej(fn(value))
        })
      })
    }

    fn(resolve, reject)
  }

  then(fn) {
    if (this.status == 'resolved') {
      const result = fn(this.value)
      return Prom.resolve(result)
    }
    if (this.status == 'pending') {
      return new Prom((resolve, reject) => {
        this.resolvedFns.push({ fn, resolve, reject })
      })
    }
  }

  catch(fn) {
    if (this.status == 'rejected') {
      const result = fn(this.value)
      return Prom.reject(result)
    }
    if (this.status == 'pending') {
      return new Prom((resolve, reject) => {
        this.rejectedFns.push({ fn, resolve, reject })
      })
    }
  }
}


new Prom((res, rej) => {
  res(10)
})
  .then(o => o * 10)
  .then(o => o + 10)
  .then(o => {
    console.log(o) // 110
  })

Promise.all

思路:和Promise.allSettled差不多 只是返回的状态并非是全部的

function promiseall(arr) {
  return new Promise((res, rej) => {
    const n = arr.length
    let num = 0
    const ans = new Array(n)
    arr.forEach((item, index) => {
      item
        .then(data => {
          ans[index] = data
          num++
          if (num == n) {
            res(ans)
          }
        })
        .catch(data => {
          rej(data)
        })
    })
  })
}

Promise.race

思路:直接对传入的Promise进行遍历执行 返回第一个执行完的结果

function myPromiseRace(promises) {
  return new Promise((resolve, reject) => {
    promises.forEach(item => {
      item
        .then(() => {
          resolve(item)
        })
        .catch(() => {
          reject(item)
        })
    })
  })
}

Promise.allSettled

思路:只需要进行每次执行完的结果都保存到数组中,最后都执行完的话 直接进行返回

function myPromiseAllSettled(promises) {
  const n = promises.length
  let num = 0
  const ans = []
  return new Promise((resolve, reject) => {
    for (let i = 0; i < n; i++) {
      prpmises[i]
        .then(() => {
          num++
          ans[i] = promises[i]
          if (num == n) resolve(ans)
        })
        .catch(() => {
          num++
          ans[i] = promises[i]
          if (num == n) resolve(ans)
        })
    }
  })
}