JS forEach 递归中断

有时处理数据需要递归,或者遍历,同时需要判定,若是中途满足了一些条件,就退出递归

如下数据:

var node = [
    { name:'a',leaf:false},
    { name:'b',leaf:true,
      children:[
       {name:'b1',leaf:true},
       {name:'b2',leaf:true}
      ],
    },
    { name:'c',leaf:false}
 ];

数组对象.forEach()

 而forEach

可枚举每一个数组元素,但并不支持类似for循环的break语法,中断循环

例如,上面的例子我们使用下

function A() {
    node.forEach((x)=>{
        if(x.leaf) return console.log('终止');
        else console.log(x.name);
    });
}

在控制台里执行:

而如果采用for循环

function B() {
   for(var i=0;i<node.length;i++) {
       var x = node[i];
       if(x.leaf) return console.log('终止');
        else console.log(x.name);
   }
}

在控制台里输出:

 

那问题来了:

又想使用forEach,又想中断咋办?


方法一:.复写forEach方法:

过程:略(自行百度)

方法二:使用抛出异常

try{
    node.forEach((x)=>{
        if(x.leaf) throw '终止'
        else console.log(x.name);
    });
}catch(r) {
    console.log(r)
}
   

那如果想进行稍微复杂点的递归后回调,应该这么处理

function A(a) {
      if(a.leaf) throw a;
    else if(a.children){
        a.children.forEach((x)=>{
            throw A(x);
        })
    } 
}
 
function B(b) {
   b.forEach((x)=>{
         try{
            A(x)
         }catch(r) {
            throw r;
         }
    })
} 
 
function C() {
 try{
    B(node)
 }catch(r) {
    console.log(r)
 }
 
}

然后控制台里执行:

注意:如果把B方法更改了

function B(b) {
   b.forEach((x)=>{
            throw A(x);//直接抛出A
    })
}

控制台里执行 无返回结果

我们再尝试把数据改复杂点

var node = [
    { name:'a',leaf:false},
    { name:'b',leaf:false,
      children:[
       {name:'b1',leaf:false},
       {name:'b2',leaf:false,
           children:[
               {name:'b21',leaf:false},
               {name:'b22',leaf:true,}
            ],
       }
      ],
    },
    { name:'c',leaf:false}
 ];

这是再次执行C()会发现,没有结果抛出

需要改造A方法:

function A(a) {
      if(a.leaf) throw a;
    else if(a.children){
        a.children.forEach((x)=>{
            try{
                 A(x) //递归时调用 也要继续抛出异常
            }catch(r) {
                  throw r;
            }
        })
    } 
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章