请实现如下的函数,可以批量请求数据,所有的URL地址在urls参数中,同时可以通过max参数 控制请求的并发度。当所有的请求结束后,需要执行callback回调。发请求的函数可以直接使用fetch。
作了一个重发次数的扩展
// 并发数控制且进行错误数重发
var p1 = () => new Promise((resolve, reject) => setTimeout(reject, 1000, 'p1'));
var p2 = () => new Promise((resolve, reject) => setTimeout(resolve, 1000, 'p2'));
var p3 = () => new Promise((resolve, reject) => setTimeout(reject, 1000, 'p3'));
var p4 = () => new Promise((resolve, reject) => setTimeout(resolve, 1000, 'p4'));
var p5 = () => new Promise((resolve, reject) => setTimeout(reject, 1000, 'p5'));
var p6 = () => new Promise((resolve, reject) => setTimeout(resolve, 1000, 'p6'));
var p7 = () => new Promise((resolve, reject) => setTimeout(reject, 1000, 'p7'));
var p8 = () => new Promise((resolve, reject) => setTimeout(resolve, 1000, 'p8'));
var p9 = () => new Promise((resolve, reject) => setTimeout(reject, 1000, 'p9'));
var p10 = () => new Promise((resolve, reject) => setTimeout(resolve, 1000, 'p10'));
var p11 = () => new Promise((resolve, reject) => setTimeout(reject, 1000, 'p11'));
var p12 = () => new Promise((resolve, reject) => setTimeout(resolve, 1000, 'p12'));
var p13 = () => new Promise((resolve, reject) => setTimeout(reject, 1000, 'p13'));
var p14 = () => new Promise((resolve, reject) => setTimeout(resolve, 1000, 'p14'));
var tasks = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14];
class TaskQueue {
/**
* 任务队列
* @param tasks 请求数组
* @param maxNum 最大并发数
* @param callTime 错误重发次数
* @param callback 回调
*/
constructor(tasks, maxNum, callTime, callback) {
this.maxNum = maxNum;
this.running = 0;
this.queue = tasks;
this.results = [];
this.callback = callback;
this.next();
this.callTime = callTime;
}
next() {
while (this.running < this.maxNum && this.queue.length) {
console.log('running');
const task = this.queue.shift();
let count = 0;
const run = async task => {
try {
const res = await task(task);
console.log('success push');
this.results.push(res);
this.running--;
this.next();
} catch (e) {
console.log('trying');
count += 1;
if (count >= this.callTime) {
console.log('fail push');
this.results.push(e);
this.running--;
this.next();
} else {
run(task);
}
}
};
run.call(this, task);
this.running++;
}
if (typeof this.callback === 'function' && this.running == 0) {
this.callback.call(null, this.results);
}
}
}
new TaskQueue(tasks, 4, 2, r => {
console.log('result', r);
});
4VM28:37 running
VM28:48 trying
VM28:43 success push
VM28:37 running
VM28:48 trying
VM28:43 success push
VM28:37 running
VM28:48 trying
VM28:51 fail push
VM28:37 running
2VM28:48 trying
VM28:51 fail push
VM28:37 running
VM28:43 success push
VM28:37 running
2VM28:48 trying
VM28:51 fail push
VM28:37 running
VM28:43 success push
VM28:37 running
2VM28:48 trying
VM28:51 fail push
VM28:37 running
VM28:43 success push
VM28:37 running
2VM28:48 trying
VM28:51 fail push
VM28:37 running
VM28:43 success push
2VM28:48 trying
VM28:51 fail push
VM28:43 success push
VM28:48 trying
VM28:51 fail push
VM28:71 result (14) ["p2", "p4", "p1", "p3", "p6", "p5", "p8", "p7", "p10", "p9", "p12", "p11", "p14", "p13"]