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)
      })
    }
  })
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章