有这么一个对象集 (子集有多少个 未知)
let result = [
{
name:"aaa",
id:"aaa111",
child:[
{
name:"bbb1",
id:"bbb111",
child:[
{
child:[],
name:"last1",
id:"111"
},
{
child:[],
name:"last2",
id:"222"
},
{
child:[],
name:"last3",
id:"333"
},
{
child:[],
name:"last4",
id:"444"
},
{
child:[],
name:"last5",
id:"555"
}
]
},
{
name:"bbb2",
id:"bbb222",
child:[]
}
]
}
];
每一级都有一个 child , 需求是, 将每一级 child 为空的数据, 整合到同一个 arr 中
如何做到呢?
肯定是使用 arr.map 的方式 递归判断
let f = (obj,f_) =>{
obj.map(item=>{
if(item.child.length == 0){
f_(item);
}else f(item.child,f_);
})
}
看起来是没问题的, 那我们假设递归数量大, 又或者出现延迟
let f = (obj,f_) =>{
obj.map(item=>{
if(item.child.length == 0){
setTimeout(()=>{
f_(item);
},30)
}else f(item.child,f_);
})
}
可以看到, 模拟了延迟后, arr 打印的是 [] , 根本原因是 异步了
那么怎么处理呢 ?
let f = (obj,f_) =>{
let o_ = [];
obj.map((item,index)=>{
if(index == (obj.length -1)){
if(item.child.length == 0){
f_(item,o_.length == 0);
if(o_.length != 0) f(o_,f_);
}else {
if(index == 0) o_ = o_.concat(item.child);
f(o_,f_);
}
}else{
if(item.child.length == 0){
f_(item,false);
}else {
o_ = o_.concat(item.child);
}
}
})
}
优化了一下后, 可以看到, 正常输出是没有问题的
那我们再来延迟一下
let f = (obj,f_) =>{
let o_ = [];
obj.map((item,index)=>{
if(index == (obj.length -1)){
if(item.child.length == 0){
// 增加延迟
setTimeout(()=>{
f_(item,o_.length == 0);
},30)
if(o_.length != 0) f(o_,f_);
}else {
if(index == 0) o_ = o_.concat(item.child);
f(o_,f_);
}
}else{
if(item.child.length == 0){
// 增加延迟
setTimeout(()=>{
f_(item,false);
},30)
}else {
o_ = o_.concat(item.child);
}
}
})
}
OK , 没得问题 !
原理是啥呢, 其实是将原来的 无序递归, 改成了, 有序递归, 先递归第一级, 在递归第二级, 依次类推, 直到没有下一级, 在 return true, 通知递归完成, 就可以避免 异步的问题了