小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

手寫(xiě)Promise實(shí)現(xiàn)過(guò)程

 行者花雕 2021-08-24
  • 1、實(shí)現(xiàn)Promise的核心功能

  • 2、判斷下當(dāng)執(zhí)行器里面時(shí)異步代碼時(shí)的回調(diào)函數(shù)調(diào)用情況

  • 3、then方法多次調(diào)用的情況

  • 4、then方法的鏈?zhǔn)秸{(diào)用,以及如何把then方法的返回值傳遞到下一個(gè)then方法中,再判斷返回值是普通值還是peomise對(duì)象進(jìn)而進(jìn)一步處理

  • 5、判斷then方法返回的對(duì)象是否和該then方法的promise對(duì)象是否相同

  • 6、捕獲錯(cuò)誤:執(zhí)行器中捕獲,成功、失敗、等待下回調(diào)函數(shù)中捕獲錯(cuò)誤

  • 7、then方法的參數(shù)變成可傳參數(shù)

  • 8、Prmomise.all()方法

  • 9、Prmomise.resolve() 方法

  • 10、finally方法

  • 11、catch方法

    // 定義好MyPromise的三種狀態(tài),用三個(gè)常量來(lái)接收
      const   PENDING = 'pending' // 等待
      const   FULFILLED = 'fulfilled'  // 成功
      const   REJECTED = 'rejected' // 失敗 
  class MyPromise {

    // MyPromise接收一個(gè)參數(shù),這個(gè)參數(shù)是構(gòu)造器函數(shù),并且在創(chuàng)建MyPromise的實(shí)例對(duì)象時(shí),這個(gè)構(gòu)造器函數(shù)會(huì)立即執(zhí)行
    constructor(executor) {
      // 構(gòu)造器函數(shù)接受兩個(gè)參數(shù):resolve、reject這兩個(gè)方法
      // 捕獲執(zhí)行器錯(cuò)誤
      try {
        executor(this.resolve, this.reject)
      } catch (e) {
        this.reject(e)
      }
    }
    // MyPromise 有三種狀態(tài) 分別是:pending、fulfilled、rejected,一開(kāi)始是pending狀態(tài)
    status = PENDING
    value = undefined   // resolve傳遞的值
    reason = undefined// reject傳遞的錯(cuò)誤信息
    // successCallBack = undefined  
    successCallBack = []  // then方法多次調(diào)用時(shí)且執(zhí)行器里面是異步時(shí)需將then方法里面的回調(diào)函數(shù)依此存儲(chǔ)在該數(shù)組中
    // failCallBack = undefined
    failCallBack = []   // 同上
    resolve = (val) => {
      if (this.status !== PENDING) return   // 如果不是pending 狀態(tài)則阻止往下執(zhí)行,因?yàn)闋顟B(tài)一旦改變,便不可更改
      // 執(zhí)行resolve方法時(shí) 狀態(tài)status修改為fulfilled
      this.status = FULFILLED
      // 將成功調(diào)用傳遞的值傳給this.value保存起來(lái)方便后續(xù)使用
      this.value = val
      // 判斷下this.successCallBack是否存在,如果存在則調(diào)用
      // this.successCallBack && this.successCallBack(this.value)

      // 從this.successCallBack中一個(gè)個(gè)取出成功回調(diào)函數(shù)調(diào)用并從數(shù)組中刪除
      // for (let i = this.successCallBack.length; i > 0; i--) {
      //   // this.successCallBack.shift()(this.value)
      //   this.successCallBack.shift()()
      // }
      while(this.successCallBack.length) this.successCallBack.shift()()
    }

    reject = (reason) => {
      if (this.status !== PENDING) return
      // 執(zhí)行resolve方法時(shí) 狀態(tài)status修改為rejected
      this.status = REJECTED
      // 將成功調(diào)用傳遞的值傳給this.value保存起來(lái)方便后續(xù)使用
      this.reason = reason
      // 同理,同上
      // this.failCallBack && this.failCallBack(this.reason)

      // 同上
      // for (let i = this.failCallBack.length; i > 0; i--) {
      //   // this.failCallBack.shift()(this.reason)
      //   this.failCallBack.shift()()
      // }
      while(this.failCallBack.length) this.failCallBack.shift()()
    }

    then(successCallBack, failCallBack) {
      /****then方法不傳遞回調(diào)函數(shù)時(shí) */
      successCallBack = successCallBack ? successCallBack : value => value
      failCallBack = failCallBack ? failCallBack : reason => { throw reason }
      /***then方法實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用 */
      // 能夠讓then方法實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用,說(shuō)明then方法返回的還是一個(gè) Promise對(duì)象,我們現(xiàn)在就再創(chuàng)建個(gè) Promise對(duì)象 promise2,并將其返回
      let promise2 = new MyPromise((resolve, reject) => {
        /**** then方法里面的回調(diào)函數(shù)仍需要立即執(zhí)行,所以我們將他們放在 promise2的執(zhí)行器函數(shù)中*/

        // 根據(jù)status的狀態(tài)判斷該調(diào)用哪個(gè)回調(diào)函數(shù),fulfilled則調(diào)用成功回調(diào)函數(shù),rejected則調(diào)用failCallBack回調(diào)函數(shù)
        if (this.status === FULFILLED) {
          // then方法返回的 promise2需要執(zhí)行 resolve 方法將當(dāng)前 then方法回調(diào)函數(shù)的返回值傳遞給下一個(gè)then方法的回調(diào)函數(shù)中 
          setTimeout(() => {
            // 捕獲回調(diào)函數(shù)錯(cuò)誤
            try {
              let x = successCallBack(this.value)
              // 需要判斷下 x 是普通值還是promise對(duì)象,
              // 如果是普通值直接調(diào)用resolve方法,
              // 如果是 Promise對(duì)象則需要查看promise對(duì)象返回的結(jié)果
              // 再根據(jù)promise對(duì)象返回的結(jié)果,決定調(diào)用resolve 還是reject
              // 此時(shí)還獲取不到promise2, 因?yàn)閜romise2需要等到new MyPromise執(zhí)行完畢之后才會(huì)獲取到,需加個(gè)異步代碼
              newPromise(promise2, x, resolve, reject)  // 將then方法返回的promise對(duì)象promise2也傳遞過(guò)去用于判斷 then方法return的x是否相同
            } catch(e) {
              reject(e)
            }
          }, 0);
          // resolve(x)
          // 調(diào)用成功回調(diào)函數(shù),并傳遞成功時(shí)的值
          //successCallBack(this.value)   // then方法被多次調(diào)用時(shí),同步情況無(wú)需處理,直接調(diào)用即可
        } else if(this.status === REJECTED) {
          // 調(diào)用失敗回調(diào)函數(shù),并傳遞失敗的原因
          //failCallBack(this.reason)     // 同上
          setTimeout(() => {
            try {
              let x = failCallBack(this.reason)
              newPromise(promise2, x, resolve, reject)
            } catch(e) {
              reject(e)
            }
          }, 0);
        } else { // 當(dāng)執(zhí)行器中時(shí)異步代碼時(shí)并沒(méi)有立即調(diào)用resolve 或reject,所以status狀態(tài)既不是fulfilled也不是 rejected,而是還處于pending狀態(tài)
          
          // this.successCallBack = successCallBack
          // 此時(shí)將then的回調(diào)函數(shù)存起來(lái)當(dāng)status狀態(tài)改變后再去調(diào)用回調(diào)函數(shù)
            // this.successCallBack.push(successCallBack)  
          // 捕獲錯(cuò)誤
          this.successCallBack.push(() =>{
            setTimeout(() => {
              try {
                let x = successCallBack(this.value)
                newPromise(promise2, x, resolve, reject)
              } catch(e) {
                reject(e)
              }
            }, 0);
          })
          // this.failCallBack = failCallBack
          // this.failCallBack.push(failCallBack)
          this.failCallBack.push(() => {
            setTimeout(() => {
              try {
                let x = failCallBack(this.reason)
                newPromise(promise2, x, resolve, reject)
              } catch(e) {
                reject(e)
              }
            }, 0);
          })
        }
      })
      return promise2;
    }

    /***finally 無(wú)論該P(yáng)romise對(duì)象是成功還是失敗都會(huì)執(zhí)行 接受一個(gè)回調(diào)函數(shù)作為參數(shù) */
    finally(callBack) {
      // finally最終返回Promise對(duì)象,而then方法返回的就時(shí)Promise對(duì)象
      return this.then(value => {
        return MyPromise.resolve(callBack()).then(() => value);
      }, reason => {
        return MyPromise.resolve(callBack()).then(() => { throw reason })
      })
    }

    /****catch方法 */
    catch (failCallBack) {
      return this.then(undefined, failCallBack)
    }

    // 靜態(tài)方法all,接受參數(shù)是一個(gè)數(shù)組
    static all(arr) {
      // all方法的then方法的回調(diào)返回值是一個(gè)數(shù)組,定義一個(gè)數(shù)組來(lái)接收
      let result = []
      let index = 0
      // 返回值是一個(gè)peomise對(duì)象
      return new MyPromise((resolve, reject) => {
        function addData(k, v) {
          result[k] = v
          index++
          if (index === result.length) {
            resolve(result)
          }
        }
        for(let i=0; i<arr.length; i++) {
          let current = arr[i]
          if(current instanceof MyPromise) {
            current.then(res => {
              addData(i, res)
            }, reason => reject(reason))
          } else {
            addData(i, arr[i])
          }
        }
      })
    }

    /**  靜態(tài)方法 resolve,返回值是一個(gè)Promise對(duì)象,接受一個(gè)參數(shù),當(dāng)這個(gè)參數(shù)是Promise對(duì)象時(shí)
     *   就將該對(duì)象作為 resolve方法的返回值,如果是個(gè)普通值,則將該值包裹在一個(gè)Promise對(duì)象中作為
     *   resolve方法的返回值 
    */
    static resolve(value) {
      if (value instanceof MyPromise) return value
      return new MyPromise((resolve) => resolve(value)) 
    }
   }


  function newPromise(promise2, x, resolve, reject) {
      if (promise2 === x) {
        return reject(new TypeError('循環(huán)返回相同的peomise對(duì)象'))  //加return 阻止代碼往下進(jìn)行
      } 
      if (x instanceof MyPromise) {
        x.then(resolve, reject)
      } else {
        resolve(x)
    }
  }

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多