本篇將結(jié)合自身使用 ES6 Promise的情況,總結(jié)下Promise在我們項目開發(fā)中的常見的應(yīng)用場景,當(dāng)然,Promise 也許不是唯一選項,但是我們作為一個合格的前端開發(fā)人員,我們有必要了解它。

Promise.all
語法:Promise.all(iterable)
參數(shù):一個可迭代對象,如Array。
返回值:
如果傳遞的iterable為空,則是已經(jīng)解決的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]
})當(dāng)給定可迭代對象中的所有promise已解決,或者任何promise均被拒絕時,此返回的promise將被異步解析/拒絕(堆棧為空時)
1. 當(dāng)給定可迭代對象中的所有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..當(dāng)給定可迭代對象中的任何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的結(jié)果很有用, 在ES6中可以將多個Promise.all異步請求并行操作:
1.當(dāng)所有結(jié)果成功返回時按照請求順序返回成功;
2.當(dāng)其中有一個失敗方法時,則進(jìn)入失敗方法;
應(yīng)用場景1:多個請求結(jié)果合并在一起
具體描述:一個頁面,有多個請求,我們需求所有的請求都返回數(shù)據(jù)后再一起處理渲染
思考:如果并發(fā)請求的話,每個請求的loading狀態(tài)要單獨設(shè)置,多個的話可能多個loading 重合,頁面顯示的內(nèi)容 根據(jù)請求返回數(shù)據(jù)的快慢 有所差異,具體表現(xiàn)在渲染的過程,為提升用戶體驗,我們可以采用 所有請求返回數(shù)據(jù)后,再一起渲染,此時我們關(guān)閉請求的單獨loading設(shè)置,通過Promise.all 匯總請求結(jié)果,從開始到結(jié)束,我們只設(shè)置一個 loading 即可。
//1.獲取輪播數(shù)據(jù)列表
function getBannerList(){
return new Promise((resolve,reject)=>{
setTimeout(function(){
resolve('輪播數(shù)據(jù)')
},300)
})
}
//2.獲取店鋪列表
function getStoreList(){
return new Promise((resolve,reject)=>{
setTimeout(function(){
resolve('店鋪數(shù)據(jù)')
},500)
})
}
//3.獲取分類列表
function getCategoryList(){
return new Promise((resolve,reject)=>{
setTimeout(function(){
resolve('分類數(shù)據(jù)')
},700)
})
}
function initLoad(){
// loading.show() //加載loading
Promise.all([getBannerList(),getStoreList(),getCategoryList()]).then(res=>{
console.log(res)
// loading.hide() //關(guān)閉loading
}).catch(err=>{
console.log(err)
// loading.hide()//關(guān)閉loading
})
}
//數(shù)據(jù)初始化
initLoad()應(yīng)用場景2:合并請求結(jié)果并處理錯誤
描述:我們需求單獨處理一個請求的數(shù)據(jù)渲染和錯誤處理邏輯,有多個請求,我們就需要在多個地方寫
思考:我們能否把多個請求合并在一起,哪怕有的請求失敗了,也返回給我們,我們只需要在一個地方處理這些數(shù)據(jù)和錯誤的邏輯即可。
//1.獲取輪播圖數(shù)據(jù)列表
function getBannerList(){
return new Promise((resolve,reject)=>{
setTimeout(function(){
// resolve('輪播圖數(shù)據(jù)')
reject('獲取輪播圖數(shù)據(jù)失敗啦')
},300)
})
}
//2.獲取店鋪列表
function getStoreList(){
return new Promise((resolve,reject)=>{
setTimeout(function(){
resolve('店鋪數(shù)據(jù)')
},500)
})
}
//3.獲取分類列表
function getCategoryList(){
return new Promise((resolve,reject)=>{
setTimeout(function(){
resolve('分類數(shù)據(jù)')
},700)
})
}
function initLoad(){
// loading.show()
Promise.all([
getBannerList().catch(err=>err),
getStoreList().catch(err=>err),
getCategoryList().catch(err=>err)
]).then(res=>{
console.log(res) // ["獲取輪播圖數(shù)據(jù)失敗啦", "店鋪數(shù)據(jù)", "分類數(shù)據(jù)"]
if(res[0] == '輪播圖數(shù)據(jù)'){
//渲染
}else{
//獲取 輪播圖數(shù)據(jù) 失敗的邏輯
}
if(res[1] == '店鋪數(shù)據(jù)'){
//渲染
}else{
//獲取 店鋪列表數(shù)據(jù) 失敗的邏輯
}
if(res[2] == '分類數(shù)據(jù)'){
//渲染
}else{
//獲取 分類列表數(shù)據(jù) 失敗的邏輯
}
// loading.hide()
})
}
initLoad()有時候頁面掛掉了,可能因為接口異常導(dǎo)致,或許只是一個無關(guān)緊要的接口掛掉了。那么一個接口掛掉了為什么會導(dǎo)致整個頁面無數(shù)據(jù)呢?Promise.all告訴我們,如果參數(shù)中 promise 有一個失敗(rejected),此實例回調(diào)失敗(reject),就不再執(zhí)行then方法回調(diào),以上用例 正好可以解決此種問題
應(yīng)用場景3:驗證多個請求結(jié)果是否都是滿足條件
描述:在一個微信小程序項目中,做一個表單的輸入內(nèi)容安全驗證,調(diào)用的是云函數(shù)寫的方法,表單有多7個字段需要驗證,都是調(diào)用的一個 內(nèi)容安全校驗接口,全部驗證通過則 可以 進(jìn)行正常的提交
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的內(nèi)容'),verify2('校驗字段2的內(nèi)容'),verify3('校驗字段3的內(nèi)容')]).then(result=>{
console.log(result)//[true, true, true]
let verifyResult = result.every(item=>item)
//驗證結(jié)果
console.log(verifyResult?'通過驗證':'未通過驗證')// 通過驗證
}).catch(err=>{
console.log(err)
})Promise.race
語法:Promise.race(iterable)
參數(shù): iterable 可迭代的對象,例如Array。可迭代的。
返回值:Promise.race(iterable) 方法返回一個 promise,一旦迭代器中的某個promise解決或拒絕,返回的 promise就會解決或拒絕
描述 race 函數(shù)返回一個 Promise,它將與第一個傳遞的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失敗(rejects),這要取決于第一個完成的方式是兩個中的哪個。
如果傳的迭代是空的,則返回的 promise 將永遠(yuǎn)等待。
如果迭代包含一個或多個非承諾值和/或已解決/拒絕的承諾,則 Promise.race 將解析為迭代中找到的第一個值。
應(yīng)用場景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;
}
//延時函數(shù),用于給請求計時
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);
});應(yīng)用場景2:請求超時提示
描述:有些時候,我們前一秒刷著新聞,下一秒進(jìn)入電梯后,手機頁面上就會提示你 “網(wǎng)絡(luò)不佳”
//請求
function request(){
return new Promise(function(resolve, reject){
setTimeout(()=>{
resolve('請求成功')
},4000)
})
}
//請求超時提醒
function timeout(){
var p = new Promise(function(resolve, reject){
setTimeout(function(){
reject('網(wǎng)絡(luò)不佳');
}, 3000);
});
return p;
}
Promise.race([
request(),
timeout()
])
.then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)//網(wǎng)絡(luò)不佳
})Promise.prototype.then
應(yīng)用場景1:下個請求依賴上個請求的結(jié)果
描述:類似微信小程序的登錄,首先需要 執(zhí)行微信小程序的 登錄 wx.login 返回了code,然后調(diào)用后端寫的登錄接口,傳入 code ,然后返回 token ,然后每次的請求都必須攜帶 token,即下一次的請求依賴上一次請求返回的數(shù)據(jù)
function A(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('B依賴的數(shù)據(jù)')
},300)
})
}
function B(prams){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(prams + 'C依賴的數(shù)據(jù)')
},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依賴的數(shù)據(jù)C依賴的數(shù)據(jù)
})
} catch(e){
}應(yīng)用場景2:中間件功能使用
描述:接口返回的數(shù)據(jù)量比較大,在一個then 里面處理 顯得臃腫,多個渲染數(shù)據(jù)分別給個then,讓其各司其職
//模擬后端返回的數(shù)據(jù)
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 常見的一些應(yīng)用場景的詳細(xì)內(nèi)容,更多請關(guān)注創(chuàng)新互聯(lián)其它相關(guān)文章!
本文標(biāo)題:Promise的常見應(yīng)用場景有哪些-創(chuàng)新互聯(lián)
URL地址:http://chinadenli.net/article40/dspieo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、微信小程序、網(wǎng)站制作、關(guān)鍵詞優(yōu)化、品牌網(wǎng)站制作、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容