Promise内部实现原理

promise内部实现原理:

function $Promise(fn) {
  // Promise 的三种状态
  this.PENDING = 'pending'
  this.RESOLVED = 'resolved'
  this.REJECTED = 'rejected'

  this.onResolvedCallback = [] // 成功回调队列
  this.onRejectedCallback = [] // 失败回调队列
  this.status = this.PENDING // 初始状态

  // 成功函数处理
  const resove = (val) => {
    if (val instanceof $Promise) {
      return value.then(resolve, reject)
    }
    this.triggerResolve(val)
  }
  // 失败函数处理
  const reject = (val) => {
    this.triggerReject(val)
  }

  try {
    // 初始同步执行
    fn(resove, reject)
  } catch (err) {
    this.triggerReject(err)
  }
}

$Promise.prototype = {
  then(onResolved, onRejected) {
    // then参数不为函数则使用空函数,缺省函数返回当前值是为了 .then().then() 场景调用
    onResolved = typeof onResolved === 'function' ? onResolved : function (value) { return value }
    onRejected = typeof onRejected === 'function' ? onRejected : function (reason) { return reason }

    // Promise的then方法返回的是新的Promise对象,状态不会更改
    return new $Promise((resolve, reject) => {
      // 成功回调事件处理
      const resolveHandle = val => {
        let res = onResolved(val)
        if (res instanceof $Promise) {
          res.then(resolve, reject)
        } else {
          resolve(res)
        }
      }
      // 失败回调事件处理
      const rejectHandle = val => {
        const res = onRejected(val)
        if (res instanceof $Promise) {
          res.then(resolve, reject)
        } else {
          reject(res)
        }
      }
      // 当状态已经确认则立即执行
      if (this.status === this.RESOLVED) {
        return resolveHandle(this.value)
      }
      if (this.status === this.REJECTED) {
        return rejectHandle(this.value)
      }
      // 当当前状态没有确认,则将回调函数放入队列,等待确认后再一次执行
      this.onResolvedCallback.push(resolveHandle)
      this.onRejectedCallback.push(rejectHandle)
    })
  },
  // 状态确认后,成功回调队列的函数依次执行
  triggerResolve(val) {
    let _this = this
    setTimeout(() => {
      _this.value = val
      if (_this.status === _this.PENDING) {
        _this.status = _this.RESOLVED
        _this.onResolvedCallback.forEach(it => {
          it(val)
        })
      }
    })
  },
  // 状态确认后,失败回调队列的函数依次执行
  triggerReject(val) {
    let _this = this
    setTimeout(() => {
      _this.value = val
      if (_this.status === _this.PENDING) {
        _this.status = _this.REJECTED
        _this.onRejectedCallback.forEach(it => {
          it(val)
        })
      }
    })
  },
  // 最后捕捉调用链错误
  catch(onRejected) {
    return this.then(null, onRejected)
  },
  // finally实现,不管成功还是失败,都执行
  finally(callback) {
    return this.then((value) => {
      return $Promise.resolve(callback()).then(() => value);
    }, (err) => {
      return $Promise.resolve(callback()).then(() => err);
    });
  }
}
// 单独调用Promise.resolve方法实现
$Promise.resolve = val => {
  return new $Promise((resolve) => {
    resolve(val)
  })
}
// 单独调用Promise.reject方法实现
$Promise.reject = val => {
  return new $Promise((resolve, reject) => {
    reject(val)
  })
}
// race函数的实现,返回结果最先完成
$Promise.race = values => {
  return new $Promise((resolve, reject) => {
    let len = values.length
    if (!len) return
    for (let i = 0; i < len; i++) {
      values[i].then(res => {
        resolve(res)
      }, error => {
        reject(error)
      })
    }
  })
}
// all函数实现,如有错误立即返回,没有错误,等待全部完成再返回
$Promise.all = values => {
  return new $Promise((resolve, reject) => {
    let len = values.length
    if (!len) return
    let resolves = []
    let nums = 0
    function processValue(i, val) {
      resolves[i] = val
      if (++nums === len) {
        resolve(resolves)
      }
    }
    for (let i = 0; i < len; i++) {
      values[i].then(res => {
        processValue(i, res)
      }, error => {
        reject(error)
      })
    }
  })
}
 
posted @ 2020-07-04 17:48  前端杂货  阅读(914)  评论(1编辑  收藏  举报