实现一个批量请求函数 multiRequest(urls, maxNum),要求如下:
- 要求最大并发数 maxNum
- 每当有一个请求返回,就留下一个空位,可以增加新的请求
- 所有请求完成后,结果按照 urls 里面的顺序依次打出
// 用于测试生成promise
let p = function (t) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve(t)
} else {
reject(t)
}
}, 1000)
})
}
function multiRequest(urls, maxNum) {
let len = urls.length,
count = 0; // promise计数
let result = new Array(len); // 请求结果
return new Promise((resolve, reject) => {
// while循环并发请求,数量小于maxNum
while (count < maxNum) {
next()
}
function next() {
let current = count++;
// 边界判断,result中不包含空值empty
// 关于边界判断,需要判断result中都是resolve或者reject的结果,不然就会产生空值
if (current >= len) {
!result.includes()&&resolve(result);
return
}
let promise = p(urls[current]);
promise.then(res => {
console.log('成功', res, Date.now())
result[current] = res;
// 递归next
if (current < len) next()
}).catch(err => {
console.log('失败', err, Date.now())
result[current] = err;
if (current < len) next()
})
}
})
}
测试结果如下:
multiRequest([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2).then(res => {
console.log(res)
})
// 输出结果
// 失败 1 1649262788371
// 成功 2 1649262788375
// 失败 3 1649262789391
// 成功 4 1649262789391
// 成功 5 1649262790405
// 成功 6 1649262790405
// 失败 7 1649262791415
// 失败 8 1649262791415
// 失败 9 1649262792425
// 成功 10 1649262792426
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
multiRequest([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3).then(res => {
console.log(res)
})
// 输出结果
// 成功 1 1649262865399
// 成功 2 1649262865403
// 失败 3 1649262865404
// 成功 4 1649262866409
// 失败 5 1649262866409
// 失败 6 1649262866409
// 成功 7 1649262867418
// 成功 8 1649262867418
// 成功 9 1649262867418
// 成功 10 1649262868433
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
题目二,具体要求如下:
//支持并发的调度器, 最多允许2两任务进行处理
const scheduler = new Scheduler(2)
scheduler.addTask(1, '1'); // 1s后输出'1'
scheduler.addTask(2, '2'); // 2s后输出'2'
scheduler.addTask(1, '3'); // 2s后输出'3'
scheduler.addTask(1, '4'); // 3s后输出'4'
scheduler.start();
这里可以使用与上面类似方式来实现
class Scheduler{
constructor(n){
this.maxNum = n;
this.tasks = []
}
addTask(delay, data){
let task = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(data)
}, delay * 1000)
})
}
this.tasks.push(task)
}
start(){
let self = this;
console.log(Date.now())
let i = 0;
while(i < this.maxNum){
next();
}
function next(){
let current = i++
if(current >= self.tasks.length) return
let task = self.tasks[current];
task().then(res => {
console.log(res, Date.now())
if (current < self.maxNum) next()
})
}
}
}
const scheduler = new Scheduler(2)
scheduler.addTask(1, '1');
scheduler.addTask(2, '2');
scheduler.addTask(1, '3');
scheduler.addTask(1, '4');
scheduler.start();
// 1649430094783
// 1 1649430095790
// 2 1649430096797
// 3 1649430096797
// 4 1649430097803
以上全部内容,如有疑问,欢迎指正。Good Luck!