class RequestQueue {
constructor(requestList, concurrency) {
this.concurrency = concurrency ? concurrency : 6 //并发量
this.attemptNum = 1 //任务尝试次数
this.status = "ready"// ready start paused successed failed
this.queue = [] // 请求池
this.failRequest = [] // 失败的请求
this.current = 0
// 添加任务
if (requestList) {
if (Array.isArray(requestList)) {
for (let i = 0; i < requestList.length; i++) {
requestList[i].requestCount = 0 // 重试次数
this.queue.push(requestList[i])
}
}
else {
throw new TypeError("workList 必须是数组 ")
}
}
}
addRequest(work) {
if (typeof work == "function") {
if (this.status == "ready" || this.status == "paused") {
work.requestCount = 0
this.queue.push(work)
} else {
console.log("当前状态无法添加任务")
}
}
}
paused() {
if (this.status == "start") {
this.status = "paused"
}
}
cancel() {
if (this.status == "ready" || this.status == "start" || this.status == "paused") {
this.status = "failed"
}
}
start() {
if (this.status == "ready" || this.status == "paused") {
this.status = "start"
for (let i = 0; i < this.concurrency; i++) {
this.core()
}
}
}
core() {
if (this.status == "start") {
if (this.current < this.concurrency && this.queue.length) {
this.current++;
console.log("----------", this.current);
const requestPromiseFactory = this.queue.shift() // 出列
requestPromiseFactory.requestCount++ //执行次数
// Promise.resolve 防止任务不是 异步的
Promise.resolve(requestPromiseFactory()).then((flag) => {
// flag 为任务返回的状态,true/false
if (!flag) {
// TODO 尝试三次失败,重新入队
if (requestPromiseFactory.requestCount < this.attemptNum) {
this.failRequest.push(requestPromiseFactory)
}
else {
// 失败
this.cancel()
throw new Error("任务异常")
}
}
this.current--
console.log("----------", this.current);
this.core() //递归调用
});
} else if (this.current == 0 && !this.queue.length) {
// 全部结束
this.status = "successed"
}
}
}
}
let done = []
for (let i = 0; i < 15; i++) {
done.push(
() => new Promise((resolve, reject) => {
setTimeout(() => {
console.log(i);
resolve(true)
}, 3000)
})
)
}
let work = new RequestQueue(done)
work.start()
setTimeout(() => {
console.log(work.status);
}, 12000)
并发请求控制
于 2024-08-16 12:01:12 首次发布