思路
思路很重要的一点就是保存promise的状态,不要让它立即resolve。而延迟执行有两种方式:
1.静态函数实现
2.await实现
静态函数
class Scheduler {
constructor() {
this.needRunTasks = []
this.runTasks = []
}
add(prmoiseFn) {
return new Promise((resolve, reject) => {
//保存Promise状态,现在不能执行
prmoiseFn.resolve = resolve;
if (this.runTasks.length < 2) {
this.run(prmoiseFn)
} else {
this.needRunTasks.push(prmoiseFn)
}
})
}
run(prmoiseFn) {
this.runTasks.push(prmoiseFn)
prmoiseFn().then(() => {
prmoiseFn.resolve()
this.runTasks.splice(this.runTasks.indexOf(prmoiseFn), 1) //移除执行后的任务
if (this.needRunTasks.length > 0) {
this.run(this.needRunTasks.shift())
}
})
}
}
await
class Scheduler {
constructor() {
this.taskNum = 0;
this.taskQueue = [];
}
async add(promiseCreator) {
//在promise内部把resolve放到任务队列中,只有当resolve被调用,后面的代码才被执行
if (this.taskNum >= 2) {
await new Promise((res) => {
this.taskQueue.push(res)
})
}
this.taskNum++;
await promiseCreator();
this.taskNum--;
if (this.taskQueue.length > 0) {
//当前任务完成后,如果任务队列里有resolve,那么就调用resolve,之前被堵住的部分就可以得到执行
this.taskQueue.shift()();
}
}
}
Promise单队列
class Scheduler {
constructor(limit) {
this.limit = limit;
this.count = 0;
this.taskArr = [];
}
add(fn) {
return new Promise((res, rej) => {
this.taskArr.push({ fn, res })
this.run()
})
}
run() {
if (this.taskArr.length && this.count < this.limit) {
this.count++;
let { fn, res } = this.taskArr.shift();
fn().then(() => {
res()
this.count--;
this.run()
})
}
}
}
测试代码
const scheduler = new Scheduler()
const promiseFn = (time) =>
new Promise(resolve => setTimeout(resolve, time))
const addTask = (time, order) =>
scheduler.add(() =>
promiseFn(time))
.then(() =>
console.log(order))
addTask(400, 4)
addTask(200, 2)
addTask(300, 3)
addTask(50, 1)
记录记录!