背景 在开发中,我们会遇到一些使用多个异步请求但返回数据需要按序的问题,如前端导出、多个文件上传,你可能会想到使用结合并发限制下分组处理使用Promise.all,虽然说这种方式可以提高请求的速度,但终归的得等到所有响应回来后才可进入下一个分组。这时候我们就可以用结合并发数,结合队列的特点让请求有序发出。 介绍 结合网上其他大佬的做法实现了一些改造,接下来让我们来介绍一下如何实现一个在限制最大同时并发数同时并在请求失败时可以重发的通用请求并发队列:
export default class RequestQueue {
constructor(maxLimit = 5, retryLimit = 2) {
this.maxLimit = maxLimit;
this.retryLimit = retryLimit;
this.taskQueue = [];
this.currentRequestCount = 0;
this.doneCount = 0;
}
async exec(request, callBack = () => {}) {
let result = [];
if (this.currentRequestCount >= this.maxLimit) {
await this.pause();
}
this.currentRequestCount++;
for (let retryCount = this.retryLimit; retryCount > 0; retryCount--) {
let done = false;
try {
result = await request();
done = true;
this.doneCount++;
return Promise.resolve(result);
} catch (error) {
if (retryCount === 1) {
done = true;
return Promise.reject(error);
}
} finally {
if (done) {
callBack(this.doneCount);
this.currentRequestCount--;
this.next();
}
}
}
}
next() {
if (this.taskQueue.length <= 0) return;
const resolve = this.taskQueue.shift();
resolve();
}
pause() {
return new Promise((resolve) => this.taskQueue.push(resolve));
}
}
使用方法:
const request = () => {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve() }, 1000)
})
};
let requestList = [];
const instance = new RequestQueue();
const callBack = () => {}
for (let i = 0; i < 100; i++ ) {
requestList.push(instance.exec(request,callBack)
.catch(err => {
console.log(err)
})
)
}
Promise.all(requestList).then((res) => {
console.log(res.falt(1))
})
.catch(err => console.log(err))
结语 感谢你的观看,这种写法可能还存在问题,仅供学习。
|