背景:
promise.all
中任何一個promise
出現(xiàn)錯誤的時候都會執(zhí)行reject
占拍,導(dǎo)致其它正常返回的數(shù)據(jù)也無法使用吓懈。
解決辦法:
- 切入點 1:
由于Promise.all(request).then(…).catch(…)
會在所有request
都resolve
時才會進then
方法,并且把所
有結(jié)果以一個數(shù)組返回花盐,只要有一個失敗,就會進catch
。而如果在單個請求中定義了catch
方法论颅,那么就
不會進Promise.all
的catch
方法。因此囱嫩,可以在單個的catch
中對失敗的promise
請求做處理恃疯,可以使
成功的請求正常返回。
function getData(api){
return new Promise((resolve,reject) => {
setTimeout(() => {
var ok = Math.random() > 0.5 // 模擬請求成功或失敗
if(ok)
resolve('get ' + api + ' data')
else{
reject('error') // 正常的reject
}
},2000)
})
}
function getDatas(arr){
var promises = arr.map(item => getData(item))
return Promise.all(promises.map(p => p.catch(e => e))).then(values => { // 關(guān)鍵步驟墨闲,map(p => p.catch(e => e)) 在每個請求后加上 catch 捕獲錯誤今妄;
values.map((v,index) => {
if(v == 'error'){
console.log('第' + (index+1) + '個請求失敗')
}else{
console.log(v)
}
})
}).catch(error => {
console.log(error)
})
}
getDatas(['./api1','./api2','./api3','./api4']).then(() => '請求結(jié)束')
- 切入點 2:
出現(xiàn)錯誤請求之后不進行reject
操作,而是繼續(xù)resolve('error)
, 之后同意交給promise.all()
進行處理.
function getData(api){
return new Promise((resolve,reject) => {
setTimeout(() => {
var ok = Math.random() > 0.5 // 模擬請求成功或失敗
if(ok)
resolve('get ' + api + ' data')
else{
// reject(api + ' fail') // 如果調(diào)用reject就會使Promise.all()進行失敗回調(diào)
resolve('error') // Promise all的時候做判斷 如果是error則說明這條請求失敗
}
},2000)
})
}
function getDatas(arr){
var promises = arr.map(item => getData(item))
return Promise.all(promises).then(values => {
values.map((v,index) => {
if(v == 'error'){
console.log('第' + (index+1) + '個請求失敗')
}else{
console.log(v)
}
})
}).catch(error => {
console.log(error)
})
}
getDatas(['./api1','./api2','./api3','./api4']).then(() => '請求結(jié)束')
- 切入點 3:
Primise.allSettled
注意:這個方法是
ES2020
中的新特性,只適用于ES2020
版本哦鸳碧!
與 Promise.all
一樣盾鳞,參數(shù)是一組包含 Promise
實例的數(shù)組,返回值是一個新的 Promise
實例瞻离,其實例在調(diào)用 then
方法中的回調(diào)函數(shù)的參數(shù)仍是一個數(shù)組腾仅。不同之處在于無論參數(shù)實例 resolve
還是 reject
, Promise.allSettled
都會執(zhí)行 then
方法的第一個回調(diào)函數(shù)(意思就是不會 catch
到參數(shù)實例的 reject
狀態(tài))套利,其回調(diào)函數(shù)的參數(shù)返回的數(shù)組的每一項是一個包含 status
和 value
或者 reason
的一組對象推励。 status
代表對應(yīng)的參數(shù)實例狀態(tài)值鹤耍,取值只有 fulfilled(resolve狀態(tài))
和 rejected(reject狀態(tài))
,當(dāng) status
的值為 rejected
验辞,對應(yīng)的另一個對象屬性就是 reason
了稿黄,也就是被 reject
的原因,而成功返回的 status
的值則是 fulfilled
跌造,對應(yīng)的另一個對象屬性便是 value
杆怕,對應(yīng)的值就是 resolve
的任意值。
var promise1 = new Promise(function(resolve,reject){
setTimeout(function(){
reject('promise1')
},2000)
})
var promise2 = new Promise(function(resolve,reject){
setTimeout(function(){
resolve('promise2')
},3000)
})
var promise3 = Promise.resolve('promise3')
var promise4 = Promise.reject('promise4')
Promise.allSettled([promise1,promise2,promise3,promise4]).then(function(args){
console.log(args);
/*
result:
[
{"status":"rejected","reason":"promise1"},
{"status":"fulfilled","value":"promise2"},
{"status":"fulfilled","value":"promise3"},
{"status":"rejected","reason":"promise4"}
]*/
})
暫時只找到三種解決方案,如有補充,后續(xù)更新.