Skip to content

手写场景

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();
        })
    }
  }
}