前端开发中涉及到并发的业务中,如何优雅的实现一个并发工具
1.涉及并发的业务场景
1.> 多文件上传,支持过程中的进度展示,暂停,删除业务
2.> 多数据源的无参静态数据分片获取,如地图业务中海量静态点位的获取分片方式的实现
3.>其他业务
2.给定一个需求场景
这里我们假设需要做一个多文件上传,支持进度等业务处理。并发的过程中要求,单次并发完成后统一返回该轮次结果。返回结果的数据顺序应该与并发开启的数据获取顺序相同。即【1,2,3】===> resolve(1,2,3)
3.开始造轮子
- 完成一个基础方法
/**
* @Description: 并发以及并发上限应用,要求并发过程中请求的结果最后统一返回。返回结果的顺序应该与发送的顺序相同。
* @Author:Eirice
* @Params:{ fnList : Function 请求函数 maxNum : Number 并发上线 }
* @Date 2024-03-04
*/
export const concurrentTodo =(fnList,maxNum)=>{
return new Promise(resolve => {
//由统一的一个resolve返回,异常的捕获由请求过程中捕获
})
}
2.针对业务定义需要处理的过程函数
export const concurrentTodo =(fnList,maxNum)=>{
let index = 0 //记录当前请求的下标
let result = [] //存储返回结果
let count = 0 // 记录当前完成的请求
return new Promise(resolve => {
async function _request() {
const i = index //记录当前请求的原始位置
const fn = fnList[index] //记录当前的获取请求
index++;
try {
console.log(index)
const resp = await fn()
result[i] = resp //为了记录指定顺序的结果需要使用原始下标进行定向数据记录到结果数组
} catch (err) {
result[i] = err //异常数据,也需要使用原始下标进行定向数据记录到结果数组
}
//完成结果的返回需要在记录的请求完成到单次并发的所有结果完成后
finally {
count++
if(count===fnList.length){
resolve(result)
}
if(index<fnList.length){
_request()
}
}
}
//开始定向的并发,按照最大的并发数量完成
for (let i=0;i<Math.min(fnList.length,maxNum);i++){
_request()
}
})
}
//防止请求数组越界,在定义的最大并发上限范围内需要结合实际的参数进行规避
for (let i=0;i<Math.min(fnList.length,maxNum);i++){
_request()
}
上结果,为了验证控制台使用了3G网络模拟
可以看到,传入的并发是4个,最大上限是3。
并发返回的结果