需求
- 控制网络请求并发数
- 控制并发按顺序返回结果
码
/**
* 控制并发
* @param {Function} fn 逻辑处理函数
* @param {Array} arr 发送的数据
* @param {Number} [max=3] 并发数 默认3
* @param {Number} [order=false] 按顺序返回执行结果 默认false
* @param {Number} [retry=1] 重试次数 默认1
* @returns {Promise} 返回Promise
*/
const reqPool = (fn, arr, max = 3, order = false, retry = 1) => {
let reqList = [...arr], //不改变arr
resData = order ? Array(reqList.length).fill(0, 0) : [], // order = true 填充返回的数据
curRuningCount = 0, //限制内的第n个并发
runedCount = 0, //已执行的数量
runingIndex = 0; //当前执行下标
return new Promise(res => {
const run = _ => {
while (curRuningCount < max && reqList.length) {
curRuningCount++
const chunk = reqList.shift();
(i => {
/**
* 当前重试次数
*/
let _retry = 0
const add = (i2, data) => fn(data)
.then(r => {
runedCount++
order ? resData[i2] = r : resData.push(r)
})
.catch(err => {
_retry++
const repMore = _retry > retry
if (!repMore) {
add(i2, data)
console.log(data, '重试' + _retry + '次');
} else {
order ? resData[i2] = err : resData.push(err)
runedCount++
}
})
.finally(_ => {
curRuningCount--
if (runedCount === arr.length) res(resData)
run()
});
add(i, chunk)
})(runingIndex++)
}
}
run()
})
}
// 请求配置 | 请求体
const chunks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
/**
* 逻辑处理函数 | 如:发起请求
* @param {Object} chunk
* @returns {Promise}
*/
const req = chunk => new Promise((res, rej) => setTimeout(_ => Math.random() > .8 ? rej('失败----' + chunk) : res('结果' + chunk), Math.random() * 100 + 100))
reqPool(req, chunks, 3, true).then(res => console.log(res))