DEV Community

Cover image for TS - 如何跳出 forEach 迴圈
FakeStandard
FakeStandard

Posted on • Edited on

TS - 如何跳出 forEach 迴圈

紀錄 Typescript forEach 如何跳出迴圈

C# 寫習慣之後要寫 TS 有些不習慣,在 TS forEach 中是不能使用 break 或 continue,只能使用 return,這對要從迴圈中跳出有些不便,先來看使用 return 跳出迴圈的結果

跳出單次迴圈

const arr1 = [1, 2, 3]

arr1.forEach(val => {
    if (val === 2) return

    console.log(val)
})

// output
// 1
// 3
Enter fullscreen mode Exit fullscreen mode

當迴圈符合條件時會執行 return,以結束此次迴圈,return 之後的程式碼不執行,但是此次之後的迴圈依然會繼續執行

跳出整個迴圈

若要直接結束掉整個迴圈需要利用 try catch 來攔截例外狀況,並且擲回例外

try {
    arr1.forEach(val => {
        if (val === 2)
            throw new Error()
            
        console.log(val)
    })
} catch (err) {
    console.log("err:" + err)
}

// output
// 1
// err:Error
Enter fullscreen mode Exit fullscreen mode

使用 try catch 包住迴圈,當迴圈內符合條件時會扔出例外,使用 catch 來攔截例外,觀察輸出發現迴圈已被中止,成功跳出整個迴圈,扔出例外後,後續迴圈皆不會執行

What about nested loops ?

先使用 return 觀察,用一個變數紀錄迴圈次數,每迭代一次就加一

const arr1 = [1, 2, 3]
const arr2 = [2, 4, 6]

let num = 0;

arr1.forEach(v1 => {
    arr2.forEach(v2 => {
        num++
        if (v1 === v2) return

        console.log(num)
    })
})

// output
// 1
// 2
// 3
// 5
// 6
// 7
// 8
// 9
Enter fullscreen mode Exit fullscreen mode

結果跟第一種情況情形一樣,迭代到第四次時,因符合條件所以該次迴圈跳出,之後無論內外層迭代還是會繼續執行

這次使用 try catch 包住內層迴圈,並將 return 替換成擲出例外狀況,當迭代到第四次時,我們攔截到例外,且內層後續的迭代被中止,但外層迴圈會持續執行

let num1 = 0;
let num2 = 0;

arr1.forEach(v1 => {
    console.log("num1:" + ++num1)
    try {
        arr2.forEach(v2 => {
            num2++
            if (v1 === v2)
                throw new Error() // 結束內層迴圈

            console.log("  num2:" + num2)
        })
    } catch (err) {
        console.log("  err:" + err)
    }
})

// output
// num1:1
//   num2:1
//   num2:2
//   num2:3
// num1:2
//   err:Error
// num1:3
//   num2:5
//   num2:6
//   num2:7
Enter fullscreen mode Exit fullscreen mode

所以要如何才能結束整個巢狀迴圈?

很簡單,只要把 try catch 移到外面包住外層迴圈,這樣當內層迴圈擲出例外後,整個巢狀迴圈就會被中止

try {
    arr1.forEach(v1 => {
        console.log("num1:" + ++num1)

        arr2.forEach(v2 => {
            num2++
            if (v1 === v2)
                throw new Error()

            console.log("  num2:" + num2)
        })
    })
} catch (err) {
    console.log("  err:" + err)
}

// output
// num1:1
//   num2:1
//   num2:2
//   num2:3
// num1:2
//   err:Error
Enter fullscreen mode Exit fullscreen mode

有個但書!雖然使用 try catch 可以攔截例外是一種中止迴圈的手段,當迴圈過大時,被 try catch 包覆住的迴圈將無法避免性能下降。所以,若有必要中止 forEach 執行,應該要使用其他語法來替代,因為上述的 try catch 絕對不是最佳解答

下篇會記錄如何使用其他語法來取代使用攔截例外中止迴圈的方法


Thanks for reading the article 🌷 🌻 🌼

If you like it, please don't hesitate to click heart button ❤️
or follow my GitHub
or buy me a coffee ⬇️ I'd appreciate it.

Buy-me-a-coffee

Top comments (0)