今天面试一道TikTok面试题要求实现一个Schedule
类的add
方法,将同时执行的promise控制在2个以内。没想出来怎么做,我只能输出2 1。😭求指导一下嘛?
class Schedule{
add(promiseCreator){
// code
}
}
const timeout = time => new Promise((resolve)=>{
setTimeout(resolve, time)
})
const schedule = new Schedule();
const addTask = (time, order)=>{
schedule
.add(()=>timeout(time))
.then(()=>{
console.log(order);
})
}
addTask(1000, 1)
addTask(500, 2)
addTask(300, 3)
addTask(400, 4)
输出应该为2 3 1 4
为了控制同时执行的 Promise 数量不超过 2 个,可以使用一个计数器来记录当前正在执行的 Promise 数量,每次执行一个 Promise 前将计数器加 1,Promise 执行完毕后将计数器减 1。当计数器小于 2 时,可以执行新的 Promise,否则将新的 Promise 添加到一个等待队列中,等待下一个 Promise 执行完毕后再执行。下面是一个可能的实现:
class Schedule {
constructor() {
this.counter = 0; // 计数器,记录当前正在执行的 Promise 数量
this.waitingQueue = []; // 等待队列,存储还未执行的 Promise
}
add(promiseCreator) {
return new Promise((resolve, reject) => {
const execute = () => {
this.counter++;
promiseCreator()
.then(resolve)
.catch(reject)
.finally(() => {
this.counter--;
if (this.waitingQueue.length > 0) {
const next = this.waitingQueue.shift();
next();
}
});
};
if (this.counter < 2) {
execute();
} else {
this.waitingQueue.push(execute);
}
});
}
}
在这个实现中,我们在构造函数中初始化了计数器和等待队列。在 add 方法中,我们首先创建一个新的 Promise,然后定义一个新的函数 execute,该函数封装了 Promise 的执行逻辑。在 execute 函数中,我们将计数器加 1,执行 Promise,然后在 finally 中将计数器减 1。如果等待队列中有等待执行的 Promise,我们从队列中取出下一个 Promise 并执行。如果当前正在执行的 Promise 数量小于 2,则可以直接执行当前的 Promise,否则将当前的 Promise 添加到等待队列中。
使用上述实现,可以得到输出为 2 1 3 4,符合预期。
可以使用一个计数器来限制同时执行的promise数量不超过两个,当计数器等于2时,将新的promise放入一个数组中等待执行。当一个promise执行完毕后,再去数组中取出等待执行的promise继续执行。
以下是代码示例:
class MyClass {
constructor() {
this.promiseCount = 0; //计数器
this.promiseQueue = []; //promise队列
}
myMethod() {
//创建一个新的Promise
const myPromise = new Promise((resolve, reject) => {
//如果计数器小于2,直接执行Promise并将计数器加1
if (this.promiseCount < 2) {
this.promiseCount++;
//模拟异步操作
setTimeout(() => {
resolve();
}, 1000);
} else {
//如果计数器大于等于2,将Promise放入队列中等待执行
this.promiseQueue.push(() => {
this.promiseCount++;
//模拟异步操作
setTimeout(() => {
resolve();
}, 1000);
});
}
});
//当Promise执行完毕后,如果队列中有等待执行的Promise,就取出并执行
myPromise.then(() => {
this.promiseCount--;
if (this.promiseQueue.length > 0) {
const nextPromise = this.promiseQueue.shift();
nextPromise();
}
});
return myPromise;
}
}
const myClass = new MyClass();
myClass.myMethod().then(() => {
console.log(1);
});
myClass.myMethod().then(() => {
console.log(2);
});
myClass.myMethod().then(() => {
console.log(3);
});
myClass.myMethod().then(() => {
console.log(4);
});
输出结果为2 3 1 4。