神族九帝's blog 神族九帝's blog
首页
  • 神卡套餐 (opens new window)
  • 神族九帝 (opens new window)
  • 网盘资源 (opens new window)
  • 今日热点 (opens new window)
  • 在线PS (opens new window)
  • IT工具 (opens new window)
  • FC游戏 (opens new window)
  • 在线壁纸 (opens new window)
  • 面试突击
  • 复习指导
  • HTML
  • CSS
  • JavaScript
  • 设计模式
  • 浏览器
  • 手写系列
  • Vue
  • Webpack
  • Http
  • 前端优化
  • 项目
  • 面试真题
  • 算法
  • 精选文章
  • 八股文
  • 前端工程化
  • 工作笔记
  • 前端基础建设与架构 30 讲
  • vue2源码学习
  • 剖析vuejs内部运行机制
  • TypeScript 入门实战笔记
  • vue3源码学习
  • 2周刷完100道前端优质面试真题
  • 思维导图
  • npm发包
  • 重学node
  • 前端性能优化方法与实战
  • webpack原理与实战
  • webGl
  • 前端优化
  • Web3
  • React
  • 更多
  • 未来要做的事
  • Stirling-PDF
  • ComfyUI
  • 宝塔面板+青龙面板
  • 安卓手机当服务器使用
  • 京东自动评价代码
  • 搭建x-ui免流服务器(已失效)
  • 海外联盟
  • 好玩的docker
  • 收藏夹
  • 更多
GitHub (opens new window)

神族九帝,永不言弃

首页
  • 神卡套餐 (opens new window)
  • 神族九帝 (opens new window)
  • 网盘资源 (opens new window)
  • 今日热点 (opens new window)
  • 在线PS (opens new window)
  • IT工具 (opens new window)
  • FC游戏 (opens new window)
  • 在线壁纸 (opens new window)
  • 面试突击
  • 复习指导
  • HTML
  • CSS
  • JavaScript
  • 设计模式
  • 浏览器
  • 手写系列
  • Vue
  • Webpack
  • Http
  • 前端优化
  • 项目
  • 面试真题
  • 算法
  • 精选文章
  • 八股文
  • 前端工程化
  • 工作笔记
  • 前端基础建设与架构 30 讲
  • vue2源码学习
  • 剖析vuejs内部运行机制
  • TypeScript 入门实战笔记
  • vue3源码学习
  • 2周刷完100道前端优质面试真题
  • 思维导图
  • npm发包
  • 重学node
  • 前端性能优化方法与实战
  • webpack原理与实战
  • webGl
  • 前端优化
  • Web3
  • React
  • 更多
  • 未来要做的事
  • Stirling-PDF
  • ComfyUI
  • 宝塔面板+青龙面板
  • 安卓手机当服务器使用
  • 京东自动评价代码
  • 搭建x-ui免流服务器(已失效)
  • 海外联盟
  • 好玩的docker
  • 收藏夹
  • 更多
GitHub (opens new window)
  • 面试突击

  • 复习指导

  • HTML

  • CSS

  • JavaScript

  • 设计模式

  • 浏览器

  • 手写系列

  • Vue

  • Webpack

  • Http

  • 前端优化

  • 项目

  • 面试真题

    • 富途证券
    • 安信证券
    • 明源云
    • 腾讯微保
    • 郑州面试题
    • 朴朴
    • 商米科技
      • 引用类型
        • 如果想要改变结果
      • 在哪里可以 catch 到报错
      • 哪个会进入微任务队列
      • 面包屑
        • 笨方法,取巧了,利用 id 的规律
        • 倒着找的方法
        • 深度优先遍历
      • 如果需求变更成了追溯从根节点到目标节点的节点路径,而不仅仅是产生 text 的路径,那么这个方案该怎么去改造
    • 海外迅雷
  • 算法

  • 精选文章

  • 八股文

  • 前端工程化

  • 面试题
  • 面试真题
wu529778790
2022-05-25

商米科技

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

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

20220526103008

# 引用类型

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 的时候已经确定了引用地址

# 如果想要改变结果

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 到报错

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

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

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

# 哪个会进入微任务队列

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

# 面包屑

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 必然是随机和没有规律的

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

# 倒着找的方法

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

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 的路径,那么这个方案该怎么去改造?

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 的路径,那么这个方案该怎么去改造


编辑 (opens new window)
上次更新: 2025/03/17, 12:21:00
朴朴
海外迅雷

← 朴朴 海外迅雷→

最近更新
01
Code Review
10-14
02
ComfyUI
10-11
03
vscode插件开发
08-24
更多文章>
Power by vuepress | Copyright © 2015-2025 神族九帝
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×