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

 

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