手写场景
1. 把一个数组扁平化为树结构
js
const arr = [
{ id: 1, name: "部门1", pid: 0 },
{ id: 2, name: "部门2", pid: 1 },
{ id: 3, name: "部门3", pid: 1 },
{ id: 4, name: "部门4", pid: 3 },
{ id: 5, name: "部门5", pid: 4 },
];
// 实现一个函数 flat2Tree,输入一个数组,输出一个树结构
function flat2Tree(arr) {
const map = {};
const ret = [];
for(const item of arr) {
map[item.id] = item;
}
for(const item of arr) {
if(item.pid === 0) {
ret.push(item);
} else {
map[item.pid].children = map[item.pid].children || [];
map[item.pid].children.push(item);
}
}
return ret;
}
// 实现一个函数 flat2Tree2,输入一个数组,输出一个树结构
function flat2Tree2(arr) {
const rets = [];
arr.forEach(item => {
//一个一个的处理,每个item都去遍历rets,看是否有pid匹配的项
const ret = dep(item, rets);
// 如果rett是undefined,说明没有匹配的项,直接push到rets中
if(!ret) {
rets.push(ret);
}
})
function dep(item, rets) {
for(const ret of rets) {
// 如果ret的id和item的pid匹配,说明item是ret的子项
if(ret.id === item.pid) {
ret.children = ret.children || [];
ret.children.push(item);
return true;
} else if(ret.children) {
// 如果ret的children中没有匹配的项,递归调用dep,继续查找
return dep(item, ret.children);
}
}
}
return rets;
}
2. 根据下面的代码实现SuperTask类
js
function timeout(delay) {
return new Promise((resolve) => {
setTimeout(() => {
resolve()
}, delay)
})
}
const superTask = new SuperTask();
function addTask(time, name) {
superTask.add(() => timeout(time))
.then(() => console.log(`任务${name}完成`));
}
addTask(10000, 1); // 10000ms后输出,任务1完成
addTask(5000, 2); // 5000ms后输出,任务2完成
addTask(3000, 3); // 8000ms后输出,任务3完成
addTask(4000, 4); // 12000ms后输出,任务4完成
addTask(5000, 5); // 15000ms后输出,任务5完成
根据输出消息得出,这是一个控制并发性的任务队列类,最大并发数为2。有点类似排队系统。
js
class SuperTask {
constructor(maxConcurrency = 2) {
this.maxConcurrency = maxConcurrency;
this.runningCount = 0;
this.taskQueue = [];
}
add(task) {
return new Promise((resolve, reject) => {
this.taskQueue.push({
task,
resolve,
reject
})
this.run();
})
}
run() {
while(this.runningCount < this.maxConcurrency && this.taskQueue.length) {
const { task, resolve, reject } = this.taskQueue.shift();
this.runningCount++;
Promise.resolve(task())
.then(resolve)
.catch(reject)
.finally(() => {
this.runningCount--;
this.run();
})
}
}
}