Open senfish opened 3 years ago
class Scheduler{
constructor(pools){
this.pools = pools || 2; // 当前运行总数量
this.queue = [];// 任务队列 先进先出
this.runs = []; // 正运行的任务
}
add(task) {
return new Promise((resolve, reject) => {
task.resolve = resolve
this.queue.push(task); // 记录到任务总数里面
if (this.runs.length < this.pools) {
this.running()
}
})
}
running() {
const task = this.queue.shift();
this.runs.push(task); // 记录一下当前runs数量
task().then(() => {
task.resolve();
// 执行完了任务之后删除this.runs里面的任务
this.runs = this.runs.filter(running => running !== task);
if (this.queue.length > 0) {
this.running();
}
})
}
}
function timeout(time){
return new Promise(resolve=>{
setTimeout(resolve,time)
})
}
var scheduler = new Scheduler()
function addTask(time,order){
scheduler
.add(()=>timeout(time))
.then(()=>console.log(order))
}
addTask(1000,1)
addTask(500,2)
addTask(300,3)
addTask(400,4)
//要求
// ouput : 2 3 1 4
//一开始1,2俩个任务进入队列
//500ms时,2完成,输出2,任务3进入队列
//800ms时,3完成,输出3,任务4进入队列
//1000ms时,1完成,输出1
//1200ms时,4完成,输出4
class Scheduler {
constructor(limit) {
this.queue = []; // 任务队列
this.running = 0; // 正在运行的个数
this.limit = limit || 2;
}
add(task){
// 返回的是一个promise,这个promise什么时候resolve呢,要等这个任务(task)成功之后在resolve
// 那这个任务(task)什么时候成功呢?在这个任务调用之后的then回调函数里面才可以resolve
return new Promise((resolve, reject) => {
task.resolve = resolve;
this.queue.push(task);
if(this.running < this.limit) {
this.run();
}
})
}
run(){
// 跟给定的任务列表不一样,这个是慢慢收集任务的,所以没办法一开始就直接填满最大并发
// 所以需要从队列里面一个个吐
if(this.queue.length === 0) return;
let task = this.queue.shift();
this.running++;
Promise.resolve(task()).then(() => {
task.resolve();
this.running--;
this.run();
})
}
}