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 ⭐ I'd appreciate it.


Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay