Promise的簡單實現(xiàn)

隨著ES6的出現(xiàn),Promise成為標準,平時使用的次數(shù)也增加。但是Promise的原理是什么,如何實現(xiàn)鏈式調(diào)用。今天就來探究一下,下面簡單實現(xiàn)了一個Promise:

class Promise {
  constructor (fn) {
    this.value = ''
    this.resolveFn = null
    this.rejectFn = null
    try {
      fn.call(this, this.resolve.bind(this), this.reject.bind(this))
    } catch (e) {
      this.reject.call(this, e)
    }
  }

  resolve (value) {
    this.value = value
    setTimeout(() => {
      this.resolveFn && this.resolveFn.call(this, value)
      return this
    }, 0)
  }

  reject (value) {
    this.value = value
    setTimeout(() => {
      console.log(this)
      this.rejectFn && this.rejectFn.call(this, value)
      return this
    }, 0)
  }

  then (onFullfilled, onRejected) {
    this.resolveFn = onFullfilled
    this.rejectFn = onRejected
    return this
  }
}

接下來來執(zhí)行一下:

var fn = new Promise((resolve, reject) => {
  console.log(111)
  resolve(333)
  console.log(222)
})

fn.then((val) => {
  console.log(val)
}, (e) => {
  console.log(e)
})

// 111
// 222
// 333

執(zhí)行結(jié)果是正確的,但是這段代碼有缺陷,只支持一個then方法,不支持多個then方法的調(diào)用,后面定義的then方法會覆蓋前面的方法。接下來來改造下:

class Promise {
  constructor (fn) {
    this.state = 'pending'
    this.callbacks = []
    try {
      fn.call(this, this.resolve.bind(this), this.reject.bind(this))
    } catch (e) {
      this.value = e
      this.reject.call(this, e)
    }
  }

  resolve (value) {
    this.state = 'fullfilled'
    this.value = value
    this.run()
  }

  reject (value) {
    this.state = 'rejected'
    this.value = value
    this.run()
  }

  then (onFullFilled, onRejected) {
    return new Promise((resolve, reject) => {
      this.handle({
        onFullFilled: onFullFilled,
        onRejected: onRejected,
        resolve: resolve,
        reject: reject
      })
    })
  }

  catch (onRejected) {
    this.state = 'rejected'
    return this.then(undefined, onRejected)
  }

  run () {
    setTimeout(() => {
      this.callbacks.forEach(callback => {
        this.handle(callback)
      })
    }, 0)
  }
  
  handle (callback) {
    if (this.callbacks.length === 0) {
      this.callbacks.push(callback)
      return
    }
    let fn = this.state === 'fullfilled' ? callback.onFullFilled : callback.onRejected
    if (!fn) {
      fn = this.state === 'fullfilled' ? callback.resolve : callback.reject
      fn(this.value)
      return
    }
    try {
      let res = fn(this.value)
      callback.resolve(res)
    } catch (e) {
      this.value = e
      callback.reject(e)
    }
  }
}
var fn = new Promise((resolve, reject) => {
  console.log(111)
  resolve(333)
  console.log(222)
})

fn.then((val) => {
  console.log(val)
}, (e) => {
  console.log(e)
})
.then((e) => {
  console.log(555)
  throw new Error('Error11')
}, (e) => {
  console.log(666)
})
.catch(e => {
  console.log(e)
  return 'aa'
})
.then((e) => {
  console.log(e)
})
image.png

至此,實現(xiàn)了Promise的簡單功能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

  • MyPromise的簡單偽實現(xiàn) Promise對象表示一個異步操作的最終結(jié)果,用來傳遞異步傳輸?shù)臄?shù)據(jù)。實現(xiàn)Prom...
    尾巴尾巴尾巴閱讀 2,163評論 0 1
  • 本文適用的讀者 本文寫給有一定Promise使用經(jīng)驗的人,如果你還沒有使用過Promise,這篇文章可能不適合你,...
    HZ充電大喵閱讀 7,456評論 6 19
  • title: promise總結(jié) 總結(jié)在前 前言 下文類似 Promise#then、Promise#resolv...
    JyLie閱讀 12,418評論 1 21
  • 你不知道JS:異步 第三章:Promises 在第二章,我們指出了采用回調(diào)來表達異步和管理并發(fā)時的兩種主要不足:缺...
    purple_force閱讀 2,249評論 0 4
  • 傳說中的鞭炮趕走了年獸,給人們帶來了平安,而現(xiàn)在的鞭炮聲聲給孩子們帶來了開心和快樂。 今年春節(jié)給兒...
    kenny515閱讀 472評論 0 1

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