最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何利用ES6進行Promise封裝總結(jié)

 更新時間:2019年02月11日 17:20:20   作者:cz160  
這篇文章主要介紹了如何利用ES6進行Promise封裝總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

原生Promise解析

簡介

promise是異步編程的一種解決方案,比傳統(tǒng)的解決方案--回調(diào)函數(shù)和事件--更合理和強大。

promise簡單說就是一個容器,里面保存著某個未來才會結(jié)束的事件(通常是一個異步操作)的結(jié)果,從語法上來說,Promise是一個對象,從它可以獲取異步操作的消息,Promise提供統(tǒng)一的API,各種異步操作都可以用同樣的方法進行處理

特點

對象的狀態(tài)不受外界影響,Promise對象代表一個異步操作,有三種狀態(tài):Pendding、fulfilled、rejected。只有異步操作的結(jié)果,可以決定當(dāng)前是哪一種狀態(tài),其他操作都無法改變這個狀態(tài)。

一旦狀態(tài)改變,就不會在變,任何時候都可以得到這個結(jié)果,只有兩種可能:從Pendding變?yōu)閒ulfilled和從Pendding變?yōu)閞ejected。只要這兩種情況發(fā)生,狀態(tài)就凝固了,會一直保持這個結(jié)果,這時就稱為resolved。

利用es6進行Promise封裝

處理同步任務(wù)

原生方法調(diào)用方式

  new Promise((resolve,reject)=>{
    resolve(1)
  }).then(res=>{
    console.log(res) //1
  })

同步封裝思考

1.由調(diào)用方式可見Promise是一個類
2.它接收一個回調(diào)函數(shù),這個回調(diào)函數(shù)接受resolve和reject方法作為參數(shù)
3.當(dāng)狀態(tài)改變后執(zhí)行then方法,并將resolve或reject的結(jié)果作為then方法接受回調(diào)函數(shù)的參數(shù)

  class Mypromise{
    constructor(callback){
      this.status='pendding'
      //成功結(jié)果
      this.s_res = null
      // 失敗結(jié)果
      this.f_res = null
      callback((arg)=>{ // 使用箭頭函數(shù)this不會丟失
       // 改變狀態(tài)為成功
       this.status = 'fulfilled'
       this.s_res = arg
      },(arg)=>{
        // 改變狀態(tài)為失敗
        this.status = 'rejected'
        this.f_res = arg 
      })
    }
    then(onresolve,onreject){
      if(this.status === 'fulfilled'){ // 當(dāng)狀態(tài)為成功時
        onresolve(this.s_res)
      }else if(this.status === 'rejected'){ // 當(dāng)狀態(tài)為失敗時
        onreject(this.f_res)
      }
    }
  }

處理異步任務(wù)

原生調(diào)用方式

  new Promise((resolve,reject)=>{
    setTimeOut(()=>{
      resolve(1)
    },1000)
  }).then(res=>{
    console.log(res)
  })

異步封裝思考

1.根據(jù)js執(zhí)行機制,setTimeOut屬于宏任務(wù),then回調(diào)函數(shù)屬于微任務(wù),當(dāng)主線程執(zhí)行完成后,會從異步隊列中取出本次的微任務(wù)先執(zhí)行。

2.也就是說,then方法執(zhí)行時,狀態(tài)還沒有改變,所有我們需要將then方法執(zhí)行的回調(diào)保存起來,等到異步代碼執(zhí)行完成后,在統(tǒng)一執(zhí)行then方法的回調(diào)函數(shù)

  class Mypromise{
    constructor(callback){
      this.status='pendding'
      //成功結(jié)果
      this.s_res = null
      // 失敗結(jié)果
      this.f_res = null
      this.query = [] // ++ 
      callback((arg)=>{ // 使用箭頭函數(shù)this不會丟失
       // 改變狀態(tài)為成功
       this.status = 'fulfilled'
       this.s_res = arg
       // 當(dāng)狀態(tài)改變后,統(tǒng)一執(zhí)行then方法的回調(diào)
       this.query.forEach(item=>{
         item.resolve(arg)
       })
      },(arg)=>{
        // 改變狀態(tài)為失敗
        this.status = 'rejected'
        this.f_res = arg 
        // 當(dāng)狀態(tài)改變后,統(tǒng)一執(zhí)行then方法的回調(diào)
       this.query.forEach(item=>{
         item.reject(arg)
       })
      })
    }
    then(onresolve,onreject){
      if(this.status === 'fulfilled'){ // 當(dāng)狀態(tài)為成功時
        onresolve(this.s_res)
      }else if(this.status === 'rejected'){ // 當(dāng)狀態(tài)為失敗時
        onreject(this.f_res)
      }else{ // ++ 狀態(tài)沒有改變
        this.query.push({ // 保存回調(diào)函數(shù)到隊列中
          resolve:onresolve,
          reject:onreject
        })
      }
    }
  } 

處理鏈?zhǔn)秸{(diào)用

原生調(diào)用方式

  new Promise((resolve,reject)=>{
    resolve(1)
  }).then(res=>{
    return res
  }).then(res=>{
    console.log(res)
  })

鏈?zhǔn)秸{(diào)用思考

原生的Promise對象的then方法,返回的也是一個Promise對象,一個新的Promise才能支持鏈?zhǔn)秸{(diào)用

下一個then方法可以接受上一個then方法的返回值作為回調(diào)函數(shù)的參數(shù)

主要考慮上一個then方法的返回值:

1.Promise對象/具有then方法的對象

2.其他值

第一個then方法返回一個Promise對象,它的回調(diào)函數(shù)接受resFn和rejFN兩個回調(diào)函數(shù)作為參數(shù),把成功狀態(tài)的處理封裝為handle函數(shù),接受成功的結(jié)果作為參數(shù)

在handle函數(shù),根據(jù)onresolve返回值的不同做出不同的處理

  class Mypromise{
    constructor(callback){
      this.status='pendding'
      //成功結(jié)果
      this.s_res = null
      // 失敗結(jié)果
      this.f_res = null
      this.query = [] // ++ 
      callback((arg)=>{ // 使用箭頭函數(shù)this不會丟失
       // 改變狀態(tài)為成功
       this.status = 'fulfilled'
       this.s_res = arg
       // 當(dāng)狀態(tài)改變后,統(tǒng)一執(zhí)行then方法的回調(diào)
       this.query.forEach(item=>{
         item.resolve(arg)
       })
      },(arg)=>{
        // 改變狀態(tài)為失敗
        this.status = 'rejected'
        this.f_res = arg 
        // 當(dāng)狀態(tài)改變后,統(tǒng)一執(zhí)行then方法的回調(diào)
       this.query.forEach(item=>{
         item.reject(arg)
       })
      })
    }
    then(onresolve,onreject){
      return new Mypromise((resFN,rejFN)=>{
        if(this.status === 'fulfilled'){ // 當(dāng)狀態(tài)為成功時
          handle(this.s_res)
        }else if(this.status === 'rejected'){ // 當(dāng)狀態(tài)為失敗時
          errBack(this.f_res)
        }else{ // ++ 狀態(tài)沒有改變
          this.query.push({ // 保存回調(diào)函數(shù)到隊列中
            resolve:onresolve,
            reject:onreject
          })
        } 
        function handle(value){
          // 當(dāng)then方法的onresolve方法有返回值時,保存其返回值,沒有使用其保存的值
          let returnVal = onresolve instanceof Function && onresolve(value) || value
          // 如果onresolve方法返回的是promise對象,則調(diào)用其then方法
          if(returnVal&&returnVal['then'] instanceof Function){
            returnVal.then(res=>{
              resFN(res)
            },err=>{
              rejFN(err)
            })
          }else{
            resFN(returnVal)
          } 
        }
        function errBack(reason){
          if(onreject instanceof Function){
            let returnVal = reject(reason)
            if(typeof returnVal !== 'undenfined' && returnVal['then'] instanceof Function){
              returnVal.then(res=>{
                resFN(res)
              },err=>{
                rejFN(err)
              })
            }else{
              resFN(returnVal)
            }
          }else{
            rejFN(reason)
          }
        }
      })
    }
  } 

Promise.all和Promise.race方法

原生調(diào)用方式

Promise.all方法接受一個數(shù)組,數(shù)組中的每一項都是一個Promise實例,只有數(shù)組中的所有Promise實例的狀態(tài)都變?yōu)閒ulfilled時,此時整個狀態(tài)才會變成fulfilled,此時數(shù)組中所有Promise實例的返回值組成一個新的數(shù)組,進行傳遞。

Promise.race方法和Promise.all方法一樣,如果不是Promise實例,就會先調(diào)用Promise.resolve方法,將參數(shù)轉(zhuǎn)為Promise實例,在進行下一步處理。

只要數(shù)組中有一個參數(shù)的狀態(tài)變?yōu)閒ulfilled就會進行傳遞

// 將現(xiàn)有對象轉(zhuǎn)換為Promise對象
  Mypromise.resolve = (arg)=>{
    if(typeof arg == 'undefined' || arg==null){ // 不帶有任何參數(shù)
      return new Mypromise(resolve=>{
        resolve(arg)
      })
    }else if(arg instanceof Mypromise){ // 是一個Mypromise實例
      return arg
    }else if(arg['then'] instanceof Function){ // 具有then方法的對象
      return new Mypromise((resolve,reject)=>{
        arg.then(res=>{
          resolve(res)
        },err=>{
          reject(err)
        })
      })
    }else{ // 參數(shù)不是具有then方法的對象,或根本不是對象
      return new Mypromise(resolve=>{
        resolve(arg)
      }) 
    }
  }
  Mypromise.all = (arr)=>{
    if(!Array.isArray(arr)){
      throw new TypeError('參數(shù)必須是一個數(shù)組')
    }
    return new Mypromise((resolve,reject)=>{
      let i=0,result=[]
      next()
      functon next(){
        // 如果不是Mypromise實例需要轉(zhuǎn)換
        Mypromise.resolve(arr[i]).then(res=>{
          result.push(res)
          i++
          if(i===arr.length){
            resolve(result)
          }else{
            next()
          }
        },reject)
      }
    })
  }
  Mypromise.race = (arr)=>{
    if(!Array.isArray(arr)){
      throw new TypeError('參數(shù)必須是一個數(shù)組')
    }
    return new Mypromise((resolve,reject)=>{
      let done = false
      arr.forEach(item=>{
        Mypromise.resolve(item).then(res=>{
          if(!done){
            resolve(res)
            done = true
          }
        },err=>{
          if(!done){
            reject(res)
            done = true
          }
        })
      })
    })
  }

處理Mypromise狀態(tài)確定不能改變的特性

在重寫callback中的resolve和reject方法執(zhí)行前,先判斷狀態(tài)是否為'pendding'

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Javascript(es2016) import和require用法和區(qū)別詳解

    Javascript(es2016) import和require用法和區(qū)別詳解

    本篇文章主要介紹了Javascript(es2016) import和require用法和區(qū)別詳解,具有一定的參考價值,有興趣的可以了解下
    2017-08-08
  • echarts學(xué)習(xí)筆記之圖表自適應(yīng)問題詳解

    echarts學(xué)習(xí)筆記之圖表自適應(yīng)問題詳解

    最近發(fā)現(xiàn)一個問題,echarts圖初始化后不能自適應(yīng)瀏覽器的縮放,所以下面這篇文章就來給大家介紹了關(guān)于echarts圖表自適應(yīng)問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • NodeJS的Promise的用法解析

    NodeJS的Promise的用法解析

    下面小編就為大家?guī)硪黄狽odeJS的Promise的用法解析。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考
    2016-05-05
  • three.js快速入門【推薦】

    three.js快速入門【推薦】

    本文主要介紹了three.js的基礎(chǔ)知識。具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • JavaScript面試題(指針、帽子和女朋友)

    JavaScript面試題(指針、帽子和女朋友)

    本文小編給大家分享一道js面試題--指針、帽子和女朋友的題目,非常有意思,感興趣的朋友參考下吧
    2016-11-11
  • js針對圖片加載失敗的處理方法分析

    js針對圖片加載失敗的處理方法分析

    這篇文章主要介紹了js針對圖片加載失敗的處理方法,結(jié)合實例形式分析了js針對圖片加載失敗時的事件監(jiān)聽、響應(yīng)等相關(guān)操作技巧,需要的朋友可以參考下
    2019-08-08
  • JS實戰(zhàn)篇之收縮菜單表單布局

    JS實戰(zhàn)篇之收縮菜單表單布局

    這篇文章主要介紹了JS實戰(zhàn)篇之收縮菜單表單布局的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-12-12
  • JavaScript用構(gòu)造函數(shù)如何獲取變量的類型名

    JavaScript用構(gòu)造函數(shù)如何獲取變量的類型名

    在JavaScript中,如何準(zhǔn)確獲取變量的類型名是一個經(jīng)常使用的問題。但是常常不能獲取到變量的精確名稱,或者必須使用jQuery 中的方法,這里通過 typeof ,jQuery.type 和 通過構(gòu)造函數(shù)來獲取變量類型這三種方法詳細(xì)介紹一遍。有需要的朋友們可以參考借鑒,下面來一起看看吧。
    2016-12-12
  • Webpack中publicPath路徑問題詳解

    Webpack中publicPath路徑問題詳解

    這篇文章主要介紹了Webpack中publicPath路徑問題詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • js遍歷子節(jié)點子元素附屬性及方法

    js遍歷子節(jié)點子元素附屬性及方法

    遍歷子節(jié)點子元素的方法有很多,本例使用js來實現(xiàn),另附示例代碼及屬性方法,需要的朋友可以參考下
    2014-08-08

最新評論

乌兰察布市| 闵行区| 大姚县| 无极县| 通河县| 巫溪县| 双峰县| 赞皇县| 施秉县| 兴仁县| 三明市| 洪洞县| 三河市| 天柱县| 汉中市| 锡林郭勒盟| 奉新县| 临泽县| 攀枝花市| 永川市| 岫岩| 桦川县| 虹口区| 于田县| 鹿泉市| 平谷区| 石河子市| 金塔县| 波密县| 理塘县| 海林市| 大同市| 乐陵市| 抚松县| 化州市| 平江县| 兴隆县| 哈巴河县| 建昌县| 礼泉县| 霍邱县|