var data = [
{ id: "0" },
{
id: "1",
children: [
{
id: "1.1",
children: [
{
id: "1.1.1",
children: [
{
id: "1.1.1.1",
children: [
{ id: "1.1.1.1.1" },
{ id: "1.1.1.1.2" },
{ id: "1.1.1.1.3" }
]
},
{ id: "1.1.1.2" },
{ id: "1.1.1.3" }
]
},
{ id: "1.1.2" },
{ id: "1.1.3" },
]
},
{ id: "1.2" },
{ id: "1.3" }
]
},
{ id: "2" },
{ id: "3" }
];
function recursive(current) {
var first = current[0];
current.shift();
var remaining = current;
console.log(first.id);
if (first.children) {
setTimeout(function(){
recursive(first.children);
})
}
if (remaining.length) {
setTimeout(function(){
recursive (remaining);
});
}
}
recursive(data);
由于setTimeout,此输出不按顺序排列
题:
>如何更改它以输出如下图所示的内容?
>我如何知道此递归函数中的最后一次迭代?列表耗尽后我需要运行一些东西.
我不能使用forEach因为我必须使用setTimeouts的原因不同.我知道setTimeout在循环中不能正常工作.有任何想法吗????
期望的输出:
解决方法:
一般来说,当您想要进行广度优先迭代时,您需要使用队列(即FIFO). Javascript没有本机队列数据结构,所以这只是使用数组和移位,但它仍然可以完成工作.
在这里,您只需将所有内容推送到每个级别的队列中.这可以保证孩子们在父母之后被推进,因此你首先要对父母进行迭代.通常使用图表,您还可以跟踪您去过的地方,但由于这是一棵树,因此没有循环.
var data = [ { id: "0" }, { id: "1", children: [ { id: "1.1", children: [ { id: "1.1.1", children: [ { id: "1.1.1.1", children: [ { id: "1.1.1.1.1" }, { id: "1.1.1.1.2" }, { id: "1.1.1.1.3" } ] }, { id: "1.1.1.2" }, { id: "1.1.1.3" } ] }, { id: "1.1.2" }, { id: "1.1.3" }, ] }, { id: "1.2" }, { id: "1.3" } ] }, { id: "2" }, { id: "3" } ];
function recursive(queue) {
var current = queue.shift();
if (current === undefined) return
console.log(current.id)
if (current.children) {
current.children.forEach(node => {
queue.push(node)
})
}
setTimeout(function() {
recursive(queue)
})
}
recursive(data);
编辑 – 深度第一:
如果你想要深度优先,你基本上使用堆栈而不是队列.这里有点奇怪,因为你关心孩子的顺序,所以我们向后加载堆栈.
var data = [ { id: "0" }, { id: "1", children: [ { id: "1.1", children: [ { id: "1.1.1", children: [ { id: "1.1.1.1", children: [ { id: "1.1.1.1.1" }, { id: "1.1.1.1.2" }, { id: "1.1.1.1.3" } ] }, { id: "1.1.1.2" }, { id: "1.1.1.3" } ] }, { id: "1.1.2" }, { id: "1.1.3" }, ] }, { id: "1.2" }, { id: "1.3" } ] }, { id: "2" }, { id: "3" } ];
function recursive(stack) {
let current = stack.pop()
if (current === undefined) return
console.log(current.id)
if(current.children) {
stack.push(...current.children.reverse())
}
setTimeout(function(){
recursive(stack)
})
}
recursive(data.reverse());