您好,登錄后才能下訂單哦!
本篇將結合自身使用 ES6 Promise的情況,總結下Promise在我們項目開發中的常見的應用場景,當然,Promise 也許不是唯一選項,但是我們作為一個合格的前端開發人員,我們有必要了解它。
Promise.all
語法:Promise.all(iterable)
參數:一個可迭代對象,如Array。
返回值:
如果傳遞的iterable為空,則是已經解決的Promise。
Promise.all([]).then(res=>{ console.log(res)//[] })
異步解析的Promise(如果傳遞的Iterable不包含Promise)。 請注意,在這種情況下,Google Chrome 58返回已解決的承諾。
Promise.all([1,2,3]).then(res=>{ console.log(res)//[1,2,3] })
當給定可迭代對象中的所有promise已解決,或者任何promise均被拒絕時,此返回的promise將被異步解析/拒絕(堆棧為空時)
1. 當給定可迭代對象中的所有promise 已解決
let promise1 = new Promise((resolve,reject)=>{ resolve(1) }) let promise2 = new Promise((resolve,reject)=>{ resolve(2) }) Promise.all([promise1,promise2,3]).then(res=>{ console.log(res)//[1,2,3] })
2..當給定可迭代對象中的任何promise被拒絕時
let promise1 = new Promise((resolve,reject)=>{ resolve(1) }) let promise2 = new Promise((resolve,reject)=>{ reject(2) }) Promise.all([promise1,promise2,3]).then(res=>{ console.log(res) }).catch(err=>{ console.log(err)//2 })
描述:
此方法對于匯總多個promise的結果很有用, 在ES6中可以將多個Promise.all異步請求并行操作:
1.當所有結果成功返回時按照請求順序返回成功;
2.當其中有一個失敗方法時,則進入失敗方法;
應用場景1:多個請求結果合并在一起
具體描述:一個頁面,有多個請求,我們需求所有的請求都返回數據后再一起處理渲染
思考:如果并發請求的話,每個請求的loading狀態要單獨設置,多個的話可能多個loading 重合,頁面顯示的內容 根據請求返回數據的快慢 有所差異,具體表現在渲染的過程,為提升用戶體驗,我們可以采用 所有請求返回數據后,再一起渲染,此時我們關閉請求的單獨loading設置,通過Promise.all 匯總請求結果,從開始到結束,我們只設置一個 loading 即可。
//1.獲取輪播數據列表 function getBannerList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('輪播數據') },300) }) } //2.獲取店鋪列表 function getStoreList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('店鋪數據') },500) }) } //3.獲取分類列表 function getCategoryList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('分類數據') },700) }) } function initLoad(){ // loading.show() //加載loading Promise.all([getBannerList(),getStoreList(),getCategoryList()]).then(res=>{ console.log(res) // loading.hide() //關閉loading }).catch(err=>{ console.log(err) // loading.hide()//關閉loading }) } //數據初始化 initLoad()
應用場景2:合并請求結果并處理錯誤
描述:我們需求單獨處理一個請求的數據渲染和錯誤處理邏輯,有多個請求,我們就需要在多個地方寫
思考:我們能否把多個請求合并在一起,哪怕有的請求失敗了,也返回給我們,我們只需要在一個地方處理這些數據和錯誤的邏輯即可。
//1.獲取輪播圖數據列表 function getBannerList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ // resolve('輪播圖數據') reject('獲取輪播圖數據失敗啦') },300) }) } //2.獲取店鋪列表 function getStoreList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('店鋪數據') },500) }) } //3.獲取分類列表 function getCategoryList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('分類數據') },700) }) } function initLoad(){ // loading.show() Promise.all([ getBannerList().catch(err=>err), getStoreList().catch(err=>err), getCategoryList().catch(err=>err) ]).then(res=>{ console.log(res) // ["獲取輪播圖數據失敗啦", "店鋪數據", "分類數據"] if(res[0] == '輪播圖數據'){ //渲染 }else{ //獲取 輪播圖數據 失敗的邏輯 } if(res[1] == '店鋪數據'){ //渲染 }else{ //獲取 店鋪列表數據 失敗的邏輯 } if(res[2] == '分類數據'){ //渲染 }else{ //獲取 分類列表數據 失敗的邏輯 } // loading.hide() }) } initLoad()
有時候頁面掛掉了,可能因為接口異常導致,或許只是一個無關緊要的接口掛掉了。那么一個接口掛掉了為什么會導致整個頁面無數據呢?Promise.all告訴我們,如果參數中 promise 有一個失敗(rejected),此實例回調失敗(reject),就不再執行then方法回調,以上用例 正好可以解決此種問題
應用場景3:驗證多個請求結果是否都是滿足條件
描述:在一個微信小程序項目中,做一個表單的輸入內容安全驗證,調用的是云函數寫的方法,表單有多7個字段需要驗證,都是調用的一個 內容安全校驗接口,全部驗證通過則 可以 進行正常的提交
function verify1(content){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(true) },200) }) } function verify2(content){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(true) },700) }) } function verify3(content){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(true) },300) }) } Promise.all([verify1('校驗字段1的內容'),verify2('校驗字段2的內容'),verify3('校驗字段3的內容')]).then(result=>{ console.log(result)//[true, true, true] let verifyResult = result.every(item=>item) //驗證結果 console.log(verifyResult?'通過驗證':'未通過驗證')// 通過驗證 }).catch(err=>{ console.log(err) })
Promise.race
語法:Promise.race(iterable)
參數: iterable 可迭代的對象,例如Array。可迭代的。
返回值:Promise.race(iterable) 方法返回一個 promise,一旦迭代器中的某個promise解決或拒絕,返回的 promise就會解決或拒絕
描述 race 函數返回一個 Promise,它將與第一個傳遞的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失敗(rejects),這要取決于第一個完成的方式是兩個中的哪個。
如果傳的迭代是空的,則返回的 promise 將永遠等待。
如果迭代包含一個或多個非承諾值和/或已解決/拒絕的承諾,則 Promise.race 將解析為迭代中找到的第一個值。
應用場景1:圖片請求超時
//請求某個圖片資源 function requestImg(){ var p = new Promise(function(resolve, reject){ var img = new Image(); img.onload = function(){ resolve(img); } //img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg"; 正確的 img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg1"; }); return p; } //延時函數,用于給請求計時 function timeout(){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ reject('圖片請求超時'); }, 5000); }); return p; } Promise .race([requestImg(), timeout()]) .then(function(results){ console.log(results); }) .catch(function(reason){ console.log(reason); });
應用場景2:請求超時提示
描述:有些時候,我們前一秒刷著新聞,下一秒進入電梯后,手機頁面上就會提示你 “網絡不佳”
//請求 function request(){ return new Promise(function(resolve, reject){ setTimeout(()=>{ resolve('請求成功') },4000) }) } //請求超時提醒 function timeout(){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ reject('網絡不佳'); }, 3000); }); return p; } Promise.race([ request(), timeout() ]) .then(res=>{ console.log(res) }).catch(err=>{ console.log(err)//網絡不佳 })
Promise.prototype.then
應用場景1:下個請求依賴上個請求的結果
描述:類似微信小程序的登錄,首先需要 執行微信小程序的 登錄 wx.login 返回了code,然后調用后端寫的登錄接口,傳入 code ,然后返回 token ,然后每次的請求都必須攜帶 token,即下一次的請求依賴上一次請求返回的數據
function A(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('B依賴的數據') },300) }) } function B(prams){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(prams + 'C依賴的數據') },500) }) } function C(prams){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(prams) },1000) }) } //我們期望的是走 try ,由于A B C模擬的請求中都是沒有reject,用 try catch 捕獲錯誤 try{ A().then( res=>B(res) ).then( res=>C(res) ).then( res=>{ console.log(res)//B依賴的數據C依賴的數據 }) } catch(e){ }
應用場景2:中間件功能使用
描述:接口返回的數據量比較大,在一個then 里面處理 顯得臃腫,多個渲染數據分別給個then,讓其各司其職
//模擬后端返回的數據 let result = { bannerList:[ {img:'輪播圖地址'} //... ], storeList:[ {name:'店鋪列表'} //... ], categoryList:[ {name:'分類列表'} //... ], //... } function getInfo(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(result) },500) }) } getInfo().then(res=>{ let { bannerList } = res //渲染輪播圖 console.log(bannerList) return res }).then(res=>{ let { storeList } = res //渲染店鋪列表 console.log(storeList) return res }).then(res=>{ let { categoryList } = res console.log(categoryList) //渲染分類列表 return res })
以上就是前端 Promise 常見的一些應用場景的詳細內容,更多請關注億速云其它相關文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。