Skip to content

很简单的题,换了种方式,就被绕进去了。

回头一看,恍然大悟,有种想把自己拍死的赶脚

20220526103008

<!-- more -->

引用类型

js
var result = [1, 2, 3];
var p = Promise.resolve(result);
result = [4, 5, 6];

p.then((r) => {
  console.log("r", r);
});

结果是r, [1, 2, 3]

resolve 的时候已经确定了引用地址

如果想要改变结果

js
var result = [1, 2, 3];
var p = Promise.resolve(result);
result[0] = 4;

p.then((r) => {
  console.log("r", r);
});

结果是r, [4, 2, 3]

在哪里可以 catch 到报错

js
const p1 = new Promise(...);
const p2 = p1.then(() => {
    throw 'fsdfsdf';
});
const p3 = p2.then(() => {...});

恍然大悟,这个就是 try catch 啊,被绕进去了,哎

毫无疑问在 p2.catch 里面捕获啊

哪个会进入微任务队列

js
const p = new Promise(codeA);
const p.then(codeB, codeC).catch(codeD);

面包屑

js
const treeNodes = [
  {
    id: "001",
    text: "父节点",
    children: [
      {
        id: "001-1",
        text: "中间节点1",
        children: [],
      },
      {
        id: "001-2",
        text: "中间节点2",
        children: [
          {
            id: "001-2-1",
            text: "子节点1",
          },
          {
            id: "001-2-2",
            text: "子节点2",
          },
        ],
      },
    ],
  },
];

// 请实现一个获取面包屑的函数
function getBreadcrumbs(treeNodes, targetId) {
  // TODO 请输入您的代码;
}

const bc = getBreadcrumbs(treeNodes, "001-2-2");
console.log(bc); // 此次将打印 父节点/中间节点2/子节点2

深度优先遍历、广度优先遍历、回溯

抽空再把算法拾起来吧,o(╥﹏╥)o

刚开始看到这道题的时候,一看面包屑,自己项目还写过,一写才发现想简单了

笨方法,取巧了,利用 id 的规律

也算是一种深度优先遍历

方案不可取哈,因为实际过程中,id 必然是随机和没有规律的

js
function getBreadcrumbs(treeNodes, targetId) {
  const ids = targetId.split("-");
  let index = 0;
  let result = "";
  const bfs = (arr, _targetId) => {
    const item = arr.find((item) => item.id === _targetId);
    if (item) {
      result = result ? `${result}/${item.text}` : item.text;
      if (_targetId !== targetId) {
        bfs(item.children, _targetId + "-" + ids[++index]);
      }
    } else {
      result = "没找到";
    }
  };

  bfs(treeNodes, ids[index]);

  return result;
}

倒着找的方法

方案本身是可行的,但是目前的实现会产生怎样的性能问题?有没有相应的优化方案?

js
function getBreadcrumbs(treeNodes, targetId) {
  let obj = {};
  let result = [];
  const findFather = (treeNodes, targetId) => {
    const _treeNodes = JSON.parse(JSON.stringify(treeNodes));
    _treeNodes.forEach((item) => {
      obj[item.id] = item;
      if (item.children) {
        item.children.forEach((child) => {
          // 标记父节点
          child.parentId = item.id;
        });
        findFather(item.children);
      }
    });
    return obj;
  };
  findFather(treeNodes, targetId);
  let head = targetId;
  while (obj[head] && obj[head].parentId) {
    result.push(obj[head].text);
    head = obj[head].parentId;
  }
  result.push(obj[head].text);
  return result.reverse().join("/");
}

深度优先遍历

方案可取,但是还是思考一下,如果需求变更成了追溯从根节点到目标节点的节点路径,而不仅仅是产生 text 的路径,那么这个方案该怎么去改造?

js
function getBreadcrumbs(treeNodes, targetId) {
  let res = "";
  const bfs = (arr, result) => {
    if (!arr) return false;
    arr.forEach((item) => {
      const _result = result ? `${result}/${item.text}` : item.text;
      if (item.id === targetId) {
        res = _result;
      } else {
        bfs(item.children, _result);
      }
    });
  };
  bfs(treeNodes, "");
  return res;
}

如果需求变更成了追溯从根节点到目标节点的节点路径,而不仅仅是产生 text 的路径,那么这个方案该怎么去改造

js