Promise 實(shí)現(xiàn)

關(guān)于Promise是什么,不做贅述。

屬性

首先一個(gè)Promise類,要有如下屬性:

  • status: pending resolved/fulfilled rejected
  • result

實(shí)例方法

  • then 返回一個(gè)promise實(shí)例,參數(shù)是兩個(gè)回調(diào)函數(shù),當(dāng)狀態(tài)轉(zhuǎn)變?yōu)閞esolved時(shí),執(zhí)行第一個(gè)回調(diào)函數(shù),當(dāng)狀態(tài)轉(zhuǎn)變?yōu)閞ejected時(shí),執(zhí)行第二個(gè)回調(diào)函數(shù)
  • catch 傳入一個(gè)回調(diào)函數(shù),相當(dāng)于then方法傳入的第二個(gè)參數(shù)
  • finally

靜態(tài)方法

  • all
  • race

實(shí)現(xiàn)

首先我們看一下Promise是怎么使用的

new Promise((resolve, reject) => {
  setTimeout(() => resolve, 100)
})

可以看出Promise對(duì)象在創(chuàng)建實(shí)例時(shí)就要執(zhí)行傳入其構(gòu)造函數(shù)的方法A,維護(hù)實(shí)例的狀態(tài),并且要重新封裝resolve和reject方法,替代A,以便第一時(shí)間獲取狀態(tài)更新。

構(gòu)造函數(shù)

function MyPromise(executor) {
  this.status = 'pending'
  this.result = null
  const resolve = (data) => {
    if (this.status !== 'pending') {
      return
    }
    this.state = 'resolved'
    this.result = data
    while (this.onResolvedCallbacks.length > 0) {
      this.onResolvedCallbacks.shift()()
      this.onRejectedCallbacks.shift()
    }
  }
  const reject = (data) => {
    if (this.status !== 'pending') return
    this.status = 'rejected'
    this.result = data
    while (this.onRejectedCallbacks.length > 0) {
      this.onResolvedCallbacks.shift()
      this.onRejectedCallbacks.shift()()
    }
  }
  executor(resolve, reject)
}
then
MyPromise.prototype.then = function (onResolved, onRejected) {
    // 如果傳入?yún)?shù)不是函數(shù),為其初始化為空函數(shù)
    onResolved = typeof onResolved === 'function' ? onResolved : ()=>{}
    onRejected = typeof onRejected === 'function' ? onRejected : ()=>{}

    return new MyPromise((resolve, reject) => {
        // this指向執(zhí)行then方法的MyPromise實(shí)例
        if(this.status === 'resolved') {
            let res = onResolved(this.result)   // then方法的返回值
            resolve(res)    // 傳遞給下一個(gè)then
        }
        if(this.status === 'rejected' && onRejected) {
            let err = onRejected(this.result)
            reject(err)
        }
        // 說明前一步還沒有完成,先保存兩個(gè)回調(diào),等待完成后再執(zhí)行
        if(this.status === 'pending') {
            this.onResolvedCallbacks.push(()=>{
                let res = onResolved(this.result)
                resolve(res)
            })
            this.onRejectedCallbacks.push(()=>{
                let err = onRejected(this.result)
                reject(err)
            })
        }
    })
}
catch
MyPromise.prototype.catch = function (onRejected) {
  if (this.status === 'rejected') {
    onRejected(this.result)
  }
  if (this.status === 'pending') {
    this.onResolvedCallbacks.push(() => {})
    this.onRejectedCallbacks.push(() => {
      onRejected(ths.result)
    })
  }
}
all
MyPromise.prototype.all = function (promiseArrary) {
  const values = []
  let count = 0
  return new MyPromise((resolve, reject) => {
    promiseArray.forEach((p, index) => {
      p = p instanceof MyPromise ? p : new MyPromise((resolve, reject) => resolve(p))
      p.then(
        (value) => {
          count++
          values[index] = value
          if (count === promiseArray.length) {
            resolve(values)
          }
        },
        (err) => reject(error)
      )
    })
  })
}
race
MyPromise.prototype.race = function(promiseArray) {
  return new Promise((resolve, reject) => {
    promiseArray.forEach((p, index) => {
      p = p instanceof Promise ? p : new Promise((resolve, reject) => resolve(p))
      p.then(value => {
        resolve(value)
      }, err => reject(err))
    })
  })
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容