国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

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

2019-11-19 12:09:47
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

原生Promise解析

簡(jiǎn)介

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

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

特點(diǎn)

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

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

利用es6進(jìn)行Promise封裝

處理同步任務(wù)

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

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

同步封裝思考

1.由調(diào)用方式可見(jiàn)Promise是一個(gè)類(lèi)
2.它接收一個(gè)回調(diào)函數(shù),這個(gè)回調(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不會(huì)丟失       // 改變狀態(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)為成功時(shí)        onresolve(this.s_res)      }else if(this.status === 'rejected'){ // 當(dāng)狀態(tài)為失敗時(shí)        onreject(this.f_res)      }    }  }

處理異步任務(wù)

原生調(diào)用方式

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

異步封裝思考

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

2.也就是說(shuō),then方法執(zhí)行時(shí),狀態(tài)還沒(méi)有改變,所有我們需要將then方法執(zhí)行的回調(diào)保存起來(lái),等到異步代碼執(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不會(huì)丟失       // 改變狀態(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)為成功時(shí)        onresolve(this.s_res)      }else if(this.status === 'rejected'){ // 當(dāng)狀態(tài)為失敗時(shí)        onreject(this.f_res)      }else{ // ++ 狀態(tài)沒(méi)有改變        this.query.push({ // 保存回調(diào)函數(shù)到隊(duì)列中          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對(duì)象的then方法,返回的也是一個(gè)Promise對(duì)象,一個(gè)新的Promise才能支持鏈?zhǔn)秸{(diào)用

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

主要考慮上一個(gè)then方法的返回值:

1.Promise對(duì)象/具有then方法的對(duì)象

2.其他值

第一個(gè)then方法返回一個(gè)Promise對(duì)象,它的回調(diào)函數(shù)接受resFn和rejFN兩個(gè)回調(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不會(huì)丟失       // 改變狀態(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)為成功時(shí)          handle(this.s_res)        }else if(this.status === 'rejected'){ // 當(dāng)狀態(tài)為失敗時(shí)          errBack(this.f_res)        }else{ // ++ 狀態(tài)沒(méi)有改變          this.query.push({ // 保存回調(diào)函數(shù)到隊(duì)列中            resolve:onresolve,            reject:onreject          })        }         function handle(value){          // 當(dāng)then方法的onresolve方法有返回值時(shí),保存其返回值,沒(méi)有使用其保存的值          let returnVal = onresolve instanceof Function && onresolve(value) || value          // 如果onresolve方法返回的是promise對(duì)象,則調(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方法接受一個(gè)數(shù)組,數(shù)組中的每一項(xiàng)都是一個(gè)Promise實(shí)例,只有數(shù)組中的所有Promise實(shí)例的狀態(tài)都變?yōu)閒ulfilled時(shí),此時(shí)整個(gè)狀態(tài)才會(huì)變成fulfilled,此時(shí)數(shù)組中所有Promise實(shí)例的返回值組成一個(gè)新的數(shù)組,進(jìn)行傳遞。

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

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

// 將現(xiàn)有對(duì)象轉(zhuǎn)換為Promise對(duì)象  Mypromise.resolve = (arg)=>{    if(typeof arg == 'undefined' || arg==null){ // 不帶有任何參數(shù)      return new Mypromise(resolve=>{        resolve(arg)      })    }else if(arg instanceof Mypromise){ // 是一個(gè)Mypromise實(shí)例      return arg    }else if(arg['then'] instanceof Function){ // 具有then方法的對(duì)象      return new Mypromise((resolve,reject)=>{        arg.then(res=>{          resolve(res)        },err=>{          reject(err)        })      })    }else{ // 參數(shù)不是具有then方法的對(duì)象,或根本不是對(duì)象      return new Mypromise(resolve=>{        resolve(arg)      })     }  }  Mypromise.all = (arr)=>{    if(!Array.isArray(arr)){      throw new TypeError('參數(shù)必須是一個(gè)數(shù)組')    }    return new Mypromise((resolve,reject)=>{      let i=0,result=[]      next()      functon next(){        // 如果不是Mypromise實(shí)例需要轉(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ù)必須是一個(gè)數(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)確定不能改變的特性

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 广河县| 修水县| 醴陵市| 博客| 姚安县| 五莲县| 河源市| 石棉县| 宜黄县| 沂水县| 宁明县| 虹口区| 南宁市| 库伦旗| 平顶山市| 永宁县| 马公市| 乌苏市| 宁海县| 万年县| 嘉荫县| 民乐县| 会昌县| 黄骅市| 中宁县| 阿拉善左旗| 静安区| 南江县| 措勤县| 松阳县| 西乡县| 沙河市| 赞皇县| 博客| 五华县| 农安县| 察雅县| 台前县| 张家口市| 长丰县| 德清县|