同时并发十个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)
})
复制代码
以上是两种方案的思考,有待实际验证。并发