同時併發十個AJAX請求,若是捕獲錯誤不超過三次就返回全部數據,超過三次返回錯誤,應該怎麼設計?promise
由於是併發,首先想到Promise.all
,可是這個是捕獲到錯誤就不朝下走了,咱們是否能夠在捕獲錯誤沒超過三次的時候,強制朝下走呢?
若是不用Promise.all
,咱們是否是能夠本身寫一個捕獲三次錯誤才返回的變異版Promise.all
?bash
咱們知道新的跨網絡異步獲取資源——fetch
,這個API自己返回的就是Promise,很是方便後續處理,因此咱們在這採用這個新接口。
第一個考慮的方案是即便捕獲到錯誤了,沒超過三次,就強行走下去。這個「強行走下去」其實說白了就是不reject
而是繼續resolve
網絡
const _fetch = (function(){
// 錯誤累計
let errorCount = 0
return (url,data = {}) => {
return fetch.post(url,data).then( res => {
// 成功以後,仍是要返回一個promise對象,由於Promise.all只接收Promise實例
return Promise.resolve(res)
}).catch( err => {
// 捕獲到錯誤的時候,由於使用閉包,因此錯誤數能夠累加
errorCount++
// 若是沒有超過3次,強行resolve,不中斷Promise.all,超過直接返回錯誤中斷
if(errorCount===3) {
Promise.reject(err)
} else {
Promise.resolve(err)
}
})
}
}())
// 調用
Promise.all([
_fetch('/a'),
_fetch('/b'),
]).then(res => {
console.log(res)
})
複製代碼
promise.all內部是捕獲一次就中斷,咱們能夠本身從新定義一個相似的方法,使之三次(或自定義次數)以後再中斷閉包
const _promiseAll = function(list) {
// promise.all最後返回的仍是一個Promise實例
return new Promise((reslove, reject) => {
let value = [] // 返回數據
let count = 0 // 返回數據累計
let errorCount = 0 // 錯誤累計
for(let [i, p] of list.entries) {
// 以防萬一,實例化list項
Promise.resolve(p).then(res => {
value[i] = res
count ++
// 若是所有走完,返回數據
if(count === list.length) resolve(values)
}).catch(err => {
errorCount ++
// 若是錯誤累計沒到3次,依然定義數據,超出三次直接返回錯誤
if(errorCount <= 3) {
value[i] = err
} else {
reject(err)
}
})
}
})
}
// 調用
_promiseAll([
fetch('/a'),
fetch('/b'),
]).then(res => {
console.log(res)
})
複製代碼
以上是兩種方案的思考,有待實際驗證。併發