手写一个Promise

2020-04-14  本文已影响0人  六寸光阴丶

写在前面

如果本文对您有所帮助,就请点个关注吧!

手写一个Promise

源代码

const reslovePromise = (promise2, x, reslove, reject) => {
  if (promise2 === x) {
    return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
  }
  if (x instanceof iPromise) {
    x.then.call(x, res => {
      reslovePromise(promise2, res, reslove, reject)
    }, err => {
      reject(err)
    })
  } else {
    reslove(x)
  }
}

class iPromise {
  constructor(executor) {
    this.state = 'pending'
    this.value = undefined
    this.reason = undefined
    this.onResolvedCallbacks = []
    this.onRejectedCallbacks = []

    const reslove = value => {
      if (value instanceof iPromise) {
        return value.then(reslove, reject)
      }
      setTimeout(() => {
        if (this.state === 'pending') {
          this.state = 'fulfilled'
          this.value = value
          this.onResolvedCallbacks.forEach(fn => fn())
        }
      }, 0)
    }

    const reject = reason => {
      setTimeout(() => {
        if (this.state === 'pending') {
          this.state = 'rejected'
          this.reason = reason
          this.onRejectedCallbacks.forEach(fn => fn())
        }
      }, 0)
    }

    executor(reslove, reject)
  }

  then(onFulfilled, onRejected) {
    const promise2 = new iPromise((reslove, reject) => {
      if (this.state === 'pending') {
        this.onResolvedCallbacks.push(() => {
          setTimeout(() => {
            const x = onFulfilled(this.value)
            reslovePromise(promise2, x, reslove, reject)
          }, 0)
        })
        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            const x = onRejected(this.reason)
            reslovePromise(promise2, x, reslove, reject)
          }, 0)
        })
      }
      if (this.state === 'fulfilled') {
        setTimeout(() => {
          const x = onFulfilled(this.value)
          reslovePromise(promise2, x, reslove, reject)
        }, 0)
      }
      if (this.state === 'rejected') {
        setTimeout(() => {
          const x = onRejected(this.reason)
          reslovePromise(promise2, x, reslove, reject)
        }, 0)
      }
    })
    return promise2
  }

  static reslove(value) {
    return new iPromise((reslove, reject) => {
      reslove(value)
    })
  }

  static reject(reason) {
    return new iPromise((reslove, reject) => {
      reject(reason)
    })
  }

  static race(promises) {
    return new iPromise((resolve, reject) => {
      promises.forEach(promise => {
        promise.then(resolve, reject)
      })
    })
  }
  
  static all(promises) {
    return new Promise((res, rej) => {
      var arr = []
      var times = 0;
      function processResult(index, result) {
        arr[index] = result
        times++;
        if (times == promiseArr.length) {
          res(arr)
        }
      }

      for (let i = 0; i < promises.length; i++) {
        var oPromise = promises[i];
        if (typeof oPromise.then == 'function') {
          oPromise.then(function (val) {
            processResult(i, val)
          }, function (reason) {
            rej(reason)
          })
        } else {
          processResult(i, oPromise)
        }
      }
    })
  }
}
上一篇 下一篇

猜你喜欢

热点阅读