面试题答案
一键面试实现代码
class Task {
constructor(name, priority, fn) {
this.name = name;
this.priority = priority;
this.fn = fn;
}
}
class TaskManager {
constructor(maxParallel) {
this.maxParallel = maxParallel;
this.queue = [];
this.running = [];
}
addTask(task) {
this.queue.push(task);
this.queue.sort((a, b) => b.priority - a.priority);
this._processQueue();
}
_processQueue() {
while (this.running.length < this.maxParallel && this.queue.length > 0) {
const task = this.queue.shift();
this._runTask(task);
}
}
_runTask(task) {
this.running.push(task);
task.fn()
.then(() => {
console.log(`Task ${task.name} completed`);
})
.catch((error) => {
console.log(`Task ${task.name} failed: ${error}`);
})
.finally(() => {
const index = this.running.indexOf(task);
if (index!== -1) {
this.running.splice(index, 1);
}
this._processQueue();
});
}
}
代码作用和原理阐述
Task
类:- 作用:用于创建任务实例,每个任务实例包含任务名称
name
、优先级priority
和具体执行的异步函数fn
。 - 原理:通过构造函数接收三个参数,将其赋值给实例属性,方便在任务管理系统中对任务进行识别、排序和执行。
- 作用:用于创建任务实例,每个任务实例包含任务名称
TaskManager
类:- 构造函数:
- 作用:初始化任务管理器,设置最大并行任务数
maxParallel
,并初始化任务队列queue
和正在运行的任务数组running
。 - 原理:接收
maxParallel
参数并赋值给实例属性,同时创建两个空数组用于后续管理任务。
- 作用:初始化任务管理器,设置最大并行任务数
addTask
方法:- 作用:向任务队列中添加任务,并根据优先级对任务队列进行排序,然后尝试处理任务队列。
- 原理:将传入的任务添加到
queue
数组,通过sort
方法按照优先级从高到低排序。然后调用_processQueue
方法尝试启动新任务。
_processQueue
方法:- 作用:检查正在运行的任务数量是否小于最大并行数且任务队列中还有任务,如果满足条件则从任务队列中取出优先级最高的任务并执行。
- 原理:使用
while
循环不断检查running
数组长度和queue
数组长度,满足条件时取出任务并调用_runTask
方法执行任务。
_runTask
方法:- 作用:执行单个任务,将任务添加到正在运行的任务数组中,执行异步函数,处理任务完成、失败和最终清理操作。
- 原理:先将任务添加到
running
数组,然后执行任务的异步函数fn
。通过then
处理任务成功的情况,catch
处理任务失败的情况,finally
处理任务无论成功或失败都要执行的清理操作,即从running
数组中移除任务,并再次调用_processQueue
方法尝试启动新任务。
- 构造函数:
使用示例
// 创建任务管理器,设置最大并行数为 2
const manager = new TaskManager(2);
// 创建任务
const task1 = new Task('Task1', 2, () => new Promise((resolve) => {
setTimeout(() => {
console.log('Task1 running');
resolve();
}, 1000);
}));
const task2 = new Task('Task2', 1, () => new Promise((resolve) => {
setTimeout(() => {
console.log('Task2 running');
resolve();
}, 2000);
}));
const task3 = new Task('Task3', 3, () => new Promise((resolve) => {
setTimeout(() => {
console.log('Task3 running');
resolve();
}, 1500);
}));
// 添加任务
manager.addTask(task1);
manager.addTask(task2);
manager.addTask(task3);
在上述使用示例中,我们创建了一个最大并行数为 2 的任务管理器,并添加了三个具有不同优先级的任务。任务会按照优先级顺序和并行限制进行执行。