// 核心:实现异步函数请求队列,规定一次最多请求内容,且对于失败的请求允许重试
class RequestQueue {
constructor(maxLimit = 5, retry = 2) {
this.currentConnect = 0;
this.maxLimit = maxLimit;
this.retry = retry;
this.blockQueue = [];
}
async request(fn, ...args) {
if (this.currentConnect >= this.maxLimit) {
await this.startBlocking();
}
this.currentConnect++;
for (let retry = this.retry; retry > 0; --retry) {
let finish = false;
try {
const data = await fn.apply(null, args);
finish = true;
return Promise.resolve(data);
} catch(e) {
if (retry === 1) {
finish = true;
return Promise.reject(e);
}
} finally {
if (finish) {
this.currentConnect--;
this.next();
}
}
}
}
startBlocking() {
let _resolve = null;
let promise = new Promise(res => _resolve = res);
this.blockQueue.push(_resolve);
return promise;
}
next() {
if (this.blockQueue.length <= 0) {
return;
}
let resolve = this.blockQueue.unshift();
resolve();
}
}
// 举例
// 正常axios请求函数
// import axios from 'axios';
// axios.get(url, params).then().catch()
// 经过转换后, 对外层的使用是没有变化的,还是传入url和params
// import axios from 'axios';
// const requestQueue = new RequestQueue();
// export function get(url, params){
// return requestQueue.run(axios.get, url, params);
// }
console