用JavaScript自己手寫一個promise

調(diào)用then的時候,如果異步任務(wù)已完成則執(zhí)行成功或失敗的回調(diào),否則掛起隊列。當(dāng)promise狀態(tài)改變的時候,調(diào)用掛起的隊列,執(zhí)行傳入的then的回調(diào)函數(shù)。


    // promise本質(zhì):狀態(tài)機
    // 1.當(dāng)狀態(tài)改變的時候,調(diào)用之前掛起的then隊列
    // 2.then的時候執(zhí)行對應(yīng)的函數(shù) 并傳參
    class MyPromise {
      constructor(fn) {
        this.res = null
        this.err = null
        this._status = 'pending' // 當(dāng)前異步任務(wù)的執(zhí)行狀態(tài)
        this._queue = [] // 等待隊列

        fn((res) => { // 異步任務(wù)成功時用戶自主調(diào)用
          // console.log('成功');
          this.res = res
          this.status = 'resolved'

          this._queue.length && this._queue.forEach(item => { // 如果等待隊列不為空 則調(diào)用傳入的成功回調(diào)
            item.fn1(res)
          })
        }, (err) => { // 異步任務(wù)失敗時用戶自主調(diào)用
          // console.log('失敗');
          this.err = err
          this.status = 'rejected'

          this._queue.length && this._queue.forEach(item => { // 如果等待隊列不為空 則調(diào)用傳入的失敗回調(diào)
            item.fn2(res)
          })
        })
      }

      static all(arr) {
        let results = []
        return new MyPromise((resolve, reject) => {
          let i = 0
          next()

          function next() {
            arr[i].then((res) => {
              results.push(res)
              i++
              if (i === arr.length) {
                resolve(results)
              } else {
                next()
              }
            }, (err) => {
              reject(err)
            })
          }
        })
      }

      then(fn1, fn2) {
        // console.log('then');
        if (this.status === 'resolved') { // 執(zhí)行then的時候異步任務(wù)已完成--狀態(tài)為成功
          fn1(this.res)
        } else if (this.status === 'rejected') { // 執(zhí)行then的時候異步任務(wù)已完成--狀態(tài)為失敗
          fn2(this.err)
        } else { // 執(zhí)行then的時候異步任務(wù)未完成
          this._queue.push({fn1, fn2})
        }
        // console.log('等待隊列', this._queue);
      }
    }




    // test
    let p1 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        resolve(1)
      }, 1000);
    })
    let p2 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        resolve(2)
      }, 1000);
    })
    p1.then((res) => {
      console.log('成功回調(diào)==>', res);
    }, (err) => {
      console.log('失敗回調(diào)==>', err);
    })

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

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

  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點點福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運大...
    HetfieldJoe閱讀 11,133評論 26 95
  • 你不知道JS:異步 第三章:Promises 在第二章,我們指出了采用回調(diào)來表達異步和管理并發(fā)時的兩種主要不足:缺...
    purple_force閱讀 2,250評論 0 4
  • title: promise總結(jié) 總結(jié)在前 前言 下文類似 Promise#then、Promise#resolv...
    JyLie閱讀 12,419評論 1 21
  • 弄懂js異步 講異步之前,我們必須掌握一個基礎(chǔ)知識-event-loop。 我們知道JavaScript的一大特點...
    DCbryant閱讀 2,886評論 0 5
  • 習(xí)慣早早起來,用心做一份早餐 晨曦的微光里,被《曾經(jīng)的你》叫醒,溫了手摸摸丫妹的臉,看她不耐煩的揉一揉鼻子側(cè)身再睡...
    風(fēng)靜竹影閑閱讀 176評論 0 4

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