实现并发限制的异步调度器
并发限制的异步调度器
实现的场景是:多文件上传 按照一定量的文件数上传,列如 2个,每次都是两个同时上传在其中一个完成才能接着后续的上传,正在上传的文件保持在一定的数量,防止数量一次性过大
* 这个调度器需要个调用限制长度 max字段
* 异步执行中的收集器 working 数组
* 待处理的异步收集器 unWork 数组
* 需要添加事件 add 判断执行中收集器是否到达上限
* 没有的话 添加到working收集器中
* 到达上限的话 unWork push
* working收集器中 异步任务执行完毕后需要删除working中的任务
并在 unWork 中取出第一个添加到working收集器中
// 调度器
class Plan {
constructor(max = 2) {
this._max = max;//执行的任务上限
this.working = [];//正在执行的任务队列
this.unWork = [];//等待的任务队列
}
add(asyncTask) {
return new Promise((resolve) => {
asyncTask.success = resolve;
if (this.working.length < this._max) {
//
this.run(asyncTask);
} else {
this.unWork.push(asyncTask);
}
console.log(this.unWork, this.working, this._max);
})
}
run(asyncTask) {
// 添加到 正在执行的任务队列中
this.working.push(asyncTask);
// 调用任务
asyncTask().then((res) => {
// 当任务执行成功
// 调用外层promise的resolve方法 会触发外层promise的then()
asyncTask.success(res);//将内层返回值 用外层promise进行返回
// 查询当前成功的正在进行任务队列中的位置 并删除掉
this.del(asyncTask)
// 取等待的任务队列的最前面 加入到执行的任务队列中
if (this.unWork.length > 0) {
this.run(this.unWork.shift());
}
})
}
del(asyncTask) {
var index = this.working.indexOf(asyncTask);
this.working.splice(index, 1); //从正在进行的任务队列中删除
}
}
// 异步pri任务!!
const timeTask = (time) => new Promise(resolve => {
setTimeout(function(){
//返回相应结果
resolve('输出结果时间'+time)
}, time);
})
const plan = new Plan();//实例化调度器
const addTask = (time, order) => {
plan.add(() => timeTask(time)).then((res) => console.log(res, '>>>>>><<<<<<<<<', order));
}
addTask(4000, 4);
addTask(8000, 2);
addTask(3000, 3);
addTask(900, 1);
去掉注释完成代码
class Plan {
constructor(max = 2) {
this._max = max;
this.working = [];
this.unWork = [];
}
add(asyncTask) {
return new Promise((resolve) => {
asyncTask.resolve = resolve;
if (this.working.length < this._max) {
this.run(asyncTask);
} else {
this.unWork.push(asyncTask);
}
})
}
run(asyncTask) {
this.working.push(asyncTask);
asyncTask().then((res) => {
asyncTask.resolve(res);
this.del(asyncTask)
if (this.unWork.length > 0) {
this.run(this.unWork.shift());
}
})
}
del(asyncTask) {
var index = this.working.indexOf(asyncTask);
this.working.splice(index, 1);
}
}
// 异步pri任务!!
const timeTask = (time) => new Promise(resolve => {
setTimeout(function(){
//返回相应结果
resolve('输出结果时间'+time)
}, time);
})
const plan = new Plan()
const addTask = (time, order) => {
plan.add(() => timeTask(time)).then((res) => console.log(res, '>>>>>><<<<<<<<<', order));
}
addTask(4000, 4);
addTask(8000, 2);
addTask(3000, 3);
addTask(900, 1);