手寫Promise簡易版


話不多說,直接上代碼

通過ES5的模塊化封裝,向外暴露一個屬性

(function(window){

  const PENDING = 'pending';

  const RESOLVED = 'fulfilled'

  const REJECTED = 'rejected'

  function MyPromise(excutor){

    const self = this;   //保存Promise對象,防止異步執行時,拿不到數據和方法,必要

    self.value = undefined;

    self.status = PENDING;

    self.callbacks = [] //當狀態沒有發生改變時,需要儲存起回調函數, 在then方法中獲取回調函數

    function resolve(value){

      self.value = value;

      self.status = RESOLVED;

      self.callbacks.map(cb => {

        setTimeout(() => { //定時器模擬異步執行,必須保證回調異步執行,否則順序就亂了

           cb.onResolved(self.value)

        })

      }) //執行保存起來的成功回調函數

    }

     function reject(value){

      self.value = value;

      self.status = REJECTED ; 

      self.callbacks.map(cb => {

        setTimeout(() => {

          cb.onRejected (self.value)

        })

      })//執行保存起來的失敗的回調函數

    }

    try{   //若在執行器函數中主動拋出錯誤,需要捕獲錯誤,並把狀態更改為rejected

      excutor(resolve,reject)

    } catch (error){

      reject(error)

    }

  }

  MyPromise.prototype.then = function( onResolved,onRejected ){

    const self = this//保存當前的Promise對象

    return new Promise(resolve,reject){

      onResolved = onResolved === 'function' ? onResolved : v => v

      onRejected  = onRejected === 'function' ? onRejected :  error => {throw error}  //實現異常透傳

      //判斷當前的狀態

      //假如Promise執行的異步任務,then方法是同步方法,那么當時Promise的狀態為pending,所以不能執行回調,此時需要保存

      if(self.status === PENDING){

        // 這里只是把回調保存了起來,並沒有改變當前的Promise對象,所以得進一步處理,處理和成功得處理類似

        self.callbacks.push({onResolved,onRejected})  //保存每一個then方法為一個對象,包含onResolved,onRejected兩個函數

      } else if(self.status === RESOLVED){

        //1. 保證then中的回調異步執行,加一個setTimeout

        //2. 在onResolved中如果主動拋出錯誤,需要捕獲錯誤

        //3. 根據Promise對象返回的結果,來決定下一個then中執行成功還是失敗的回調

        //4. 如果上一個Promise返回的是一個值,如return 2,那么直接用resolve(2)執行

        //5. 如果上一個Promise返回的是一個promise對象,那么要通過promise.then 來獲取promise的執行結果

        setTimeout(() => {

          try { 

             const result = onResolved(self.value)

            if( result instanceof MyPromise){ //判斷返回值是不是Promise對象

              //返回一個Promise對象

              result.then( 

                value => {  //返回值是Promise對象,並且是成功的,那么就會執行這一個函數

                  resolve(self.value)

                }  

                error => {  //返回值是Promise對象,並且是失敗的,那么就會執行這一個函數

                  rejecte(self.value)

                }

              )  

            }else {  //返回的不是一個Promise對象

               resolve(self.value)

            }

          } catch (error) {

             //與成功的處理一樣,只需要更改一下回調函數,太長就不寫了

          }

        })

      } else { //rejected狀態}  

      }

    }

  window.MyPromise = MyPromise //向外暴露方法

})(window)

 

到這里就差不多寫完簡易的promise了,了解了原理也能更好的使用promise

歡迎指正,若有不清楚,也可評論指出


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM