商米科技
很简单的题,换了种方式,就被绕进去了。
回头一看,恍然大悟,有种想把自己拍死的赶脚
# 引用类型
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)
上次更新: 2024/11/29, 10:10:04