Promise.all 中处理 reject 失败请求的重发机制
在使用 Promise.all 并发请求时,单个请求失败会触发整体 catch。为解决国内网络超时导致的请求失败问题,本文介绍在单个请求内部定义 catch 方法,将失败的 promise 加入列表,待一轮请求结束后对失败列表进行重发的策略,从而避免整体中断。
Promise.all 中处理 reject 失败请求的重发机制
在开发爬虫程序时,使用 axios.all 并发请求多个页面,常因国内网络波动导致超时并触发 reject。简单的 resolve 策略无法覆盖所有情况,因此需要实现一种针对失败请求的重发机制。
Promise.all(requestPromises).then(...).catch(...) 的行为是:只有当所有 requestPromises 都 resolve 时,才会进入 then 方法并返回结果数组;只要有一个请求失败,就会直接进入 catch。如果在单个请求中预先定义了 catch 方法,则该错误不会向上冒泡至 Promise.all 的 catch。基于此特性,可以在单个请求的 catch 中将失败的 promise 存入列表,待一轮请求全部结束后,再对失败列表发起重发请求。
let failedList = []
function getDataById (id) { // 这是单个请求
return new Promise(function (resolve, reject) {
getResponse(id, resolve, reject)
}).catch(e => {
failedList.push(arguments.callee(id)) // 如果失败,就重新发起请求,并将该请求的promise放入failedList中以便后续处理
})
}
function getResponse (id, resolve, reject) { // 模拟返回结果
setTimeout(() => {
if (Math.random() > 0.8) resolve({id, msg: 'ok'})
else reject({id, msg: 'error'})
}, 1000)
}
const RequestList = [getDataById(1), getDataById(2), getDataById(3)]
fetchData(RequestList)
let counter = 1 // 请求次数
let maxRequestTimes = 5 // 最大请求次数,因为有可能别个页面就是访问不了,请求多少次也没用- -
let result = [] // 最后的结果
function fetchData (requestList) { // 这里是对请求结果的处理
Promise.all(requestList).then(resolve => {
result = result.concat(resolve.filter(i => i)) // filter返回true的时候保留该数组项,因为getDataById的catch里没有给返回值(这里也不需要),这里的resolve里就会有undefined,需要过滤掉
let failedLength = failedList.length
if (failedLength > 0 && counter < maxRequestTimes) { // 如果失败列表里有请求,并且请求次数不超过设定的值,就进行下一次请求,并且打出log
console.log(`第${counter}次请求完成,其中成功${RequestList.length - failedLength}个,失败${failedLength}个,正在进行第${++counter}次请求...`)
fetchData(failedList)
failedList = [] // 这里要清空failedList,不然会一直调用。不用担心,下一次请求失败的会在getDataById填充到failedList里。
} else { // 表示所有请求都成功了,或者达到了最大请求次数。到这里就可以对result做进一步处理了。
console.log(`请求完成,共请求${counter}次, 其中成功${RequestList.length - failedLength}个,失败${failedLength}个\n`, result)
counter = 1
}
}).catch(e => {
console.log(e)
})
}

总结
以上所述是小编给大家介绍的Promise.all中对于reject的处理方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对本站网站的支持!
JS合并多个数组的三种方法:concat、spread与flat
2026-11-05 17:39:45
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
