日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

通過一個實際案例徹底理解 promise

 印度阿三17 2019-07-19

JavaScrip 是單線程,前端在大部分情況下寫出來的 JS 代碼都是同步執(zhí)行。偶爾會通過回調(diào)函數(shù)達到異步執(zhí)行的目的。后來有了 promise 對象解決異步問題,被納入到 ES6 標準中。

但是很多人都不理解 promise,或者一知半解,感覺懂又好像不懂,最主要的是在實際項目中用得少,不能夠?qū)W以致用,融會貫通。但也正是因為不能夠真正理解所以也不敢貿(mào)然用在項目中,于是兩者陷入循環(huán),導致很多人對這個既能夠提高代碼質(zhì)量,又在一定程度上提升性能的對象棄之不用。

我從前對 promise 的印象也是停留在以上階段,直到今天,在一個實際開發(fā)案例中運用到了 promise ,讓我對 promise 有了深刻的理解,在此分享給大家。

案例

在這里插入圖片描述
在以上的頁面中,有一個點贊功能,是上級看過記錄之后進行評價的反饋。
上級打開下屬的記錄詳情之后,涉及到的邏輯如下

  1. 調(diào)登陸接口,拿到上級userId。

  2. 調(diào)點贊列表接口。

  3. 通關(guān)上級的 userId,與點贊列表接口里面對應(yīng)的點贊 id 比較,如果上級點過贊,則點贊的圖標是實心。否則是空心。

案例分析

實現(xiàn)以上功能需要調(diào)兩個接口。首先調(diào)登陸接口,拿到 userId,然后在回調(diào)中再調(diào)點贊列表接口,循環(huán)列表,拿到點贊 id ,與 userId 做比較。代碼如下:

第一步:調(diào)用登陸接口,拿到 userId

function getUserId(cb){
axios.post(Config.serverUrl   "/login/login", 
{code: result.code,
url:url,}, {
headers: {'Content-Type': 'application/json'}
}).then(res => {
if (res.data.isSuc == true) {
sessionStorage.setItem(Config.SESSION_DING_USER,JSON.stringify(res.data.result));
let s = sessionStorage.getItem(Config.SESSION_DING_USER);
let user = JSON.parse(s);
let userId = user && user.userid;
if(cb){
cb(userId);
}
} else {
      alert(登錄失敗);}
})
}

第二步,調(diào)用點贊列表接口

function getPraiseList(cb){
            axios.post(Config.serverUrl   "/visitAndSign/getpraiseInfo", {
                "signId": Number(self.id),
            }, {
                headers: {'Content-Type': 'application/json', 'DING_TOKEN': self.token}
            }).then(function (res) {
                if (res.data.isSuc) {
                    let list = res.data.result;
                    if(cb){
                        cb(list);
                    }
                }
            })
        }

第三步,根據(jù)回調(diào)結(jié)果,判斷是否點過贊

getUserId(function (userId){
  getPraiseList(function(list){
   for (var i=0;i<list.length;i  ){
            if(list[i].praiseUserid == userId){
              self.isPraise = 0;
              break;
          }
    }
})
})

通過 Promise 對案例進行優(yōu)化

以上通過兩層回調(diào)可以實現(xiàn)業(yè)務(wù)邏輯,咋一看沒什么大問題,但是如果業(yè)務(wù)還沒完,假設(shè)又增加一個需求,根據(jù)點贊狀態(tài)判斷是否調(diào)用另一個接口。這樣就會陷入回調(diào)地獄,回調(diào)地獄主要是指回調(diào)太多,代碼冗長,到最后很有可能你都不知道那個回調(diào)對應(yīng)的那個參數(shù)了。
為了優(yōu)雅的解決以上問題,Promise 對象閃亮登場,現(xiàn)在使用 Promise 實現(xiàn)以上功能。并且假設(shè)得到是否點贊狀態(tài)之后還要調(diào)第三個接口。

第一步優(yōu)化,使用 Promise 對象和 .then() 方法

var promise = new Promise(function(resolve,reject){
axios.post(Config.serverUrl   "/login/login", 
{code: result.code,
url:url,}, {
headers: {'Content-Type': 'application/json'}
}).then(res => {
if (res.data.isSuc == true) {
sessionStorage.setItem(Config.SESSION_DING_USER,JSON.stringify(res.data.result));
let s = sessionStorage.getItem(Config.SESSION_DING_USER);
let user = JSON.parse(s);
let userId = user && user.userid;
resolve(userId);
}})
})

promise.then(function(userId){
axios.post(Config.serverUrl   "/visitAndSign/getpraiseInfo", {
                "signId": Number(self.id),
}, {
headers: {'Content-Type': 'application/json', 'DING_TOKEN': self.token}
            }).then(function (res) {
                if (res.data.isSuc) {
                    let list = res.data.result;
                    for (var i=0;i<list.length;i  ){
                   if(list[i].praiseUserid == userId){
                   self.isPraise = 0;
                   break;
                   }
                  }
                  return self.isPraise;
                }
            })
})
.then(function(res){
console.log(res)//點贊狀態(tài)實現(xiàn)結(jié)果,這里可以繼續(xù)調(diào)第三個接口
})
//后面如果還有回調(diào)繼續(xù)用.then()即可。

第二步優(yōu)化,使用 Promise.all 優(yōu)化性能
雖然通過 Promise 對象解決了代碼展示問題。還有一個問題,等到登陸接口調(diào)成功之后再調(diào)點贊列表接口。但是實際上點贊列表接口并不依賴于登陸接口。所以登陸接口和點贊列表接口可以同時調(diào),加快接口返回速度,但問題是,做最后的對比處理(點贊列表編號與用戶編號對比來判斷用戶是否點過贊)需要在兩個接口都成功返回才可。所以這時候就用上了 Promise.all。

Promise.all 接收一個數(shù)組,而數(shù)組中就是每一個 Promise 對象。假設(shè) Promise.all 的返回結(jié)果定義為 pro。pro.then()就是兩個接口都調(diào)成功之后的回調(diào)。

對以上代碼進一步改造如下:

var promise1 = new Promise(function(resolve,rejuect){
axios.post(Config.serverUrl   "/login/login", 
{code: result.code,
url:url,}, {
headers: {'Content-Type': 'application/json'}
}).then(res => {
if (res.data.isSuc == true) {
sessionStorage.setItem(Config.SESSION_DING_USER,JSON.stringify(res.data.result));
let s = sessionStorage.getItem(Config.SESSION_DING_USER);
let user = JSON.parse(s);
let userId = user && user.userid;
resolve(userId);
}})
})
var promise2 = new Promise(function(resolve,rejuect){
axios.post(Config.serverUrl   "/visitAndSign/getpraiseInfo", {
                "signId": Number(self.id),
}, {
headers: {'Content-Type': 'application/json', 'DING_TOKEN': self.token}
            }).then(function (res) {
                if (res.data.isSuc) {               
                  resolve(res.data.result);
                }
            })
})
})
var pro = Promise.all([promise1,promise2]);
pro.then(function(userId,list){
     for (var i=0;i<list.length;i  ){
    if(list[i].praiseUserid == userId){
    self.isPraise = 0;
        break;
     }
 }
})

總結(jié)

  1. Promise 對象用法

var  promise = new Promise(function(resolve,rejuct){
if(){
//異步方法調(diào)用成功
   resolve();
}else{
//異步方法調(diào)用失敗
   rejuct();
}
})
promise.then(function(){

})

舉例:

    var  promise = new Promise(function(resolve,reject){
        setTimeout(function (res) {
            resolve(res);
        },2000,1);
    })
    promise.then(function(id){
        console.log(id)//1
    })
  1. Promise.all() 用法

var  promise1 = new Promise(function(resolve,rejuct){
if(){
//異步方法調(diào)用成功
   resolve();
}else{
//異步方法調(diào)用失敗
   rejuct();
}
})
var  promise2 = new Promise(function(resolve,rejuct){
if(){
//異步方法調(diào)用成功
   resolve();
}else{
//異步方法調(diào)用失敗
   rejuct();
}
})
var pro = Promise.all([promise1,promise2])
pro.then(function([a,b]){
   //在這里a和b都可以拿到
})

舉例:

var  promise1 = new Promise(function(resolve,reject){
        setTimeout(function (res) {
            resolve(res);
        },2000,1);
    })
    var  promise2 = new Promise(function(resolve,reject){
        setTimeout(function (res) {
            resolve(res);
        },3000,2);
    })
    var pro = Promise.all([promise1,promise2]);
    pro.then(function([a,b]){
        console.log(a b)//3
    })
  1. 雖然不使用一些新語法和高階用法也能實現(xiàn)一些功能,但是新語法和用法的誕生必定是解決了某個問題或提升了性能。所以在平時項目中還是要經(jīng)常將一些高階用法運用進去,如果不去實踐,有些概念很難真正理解。

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多