kotlin: 不要用 try-catch 直接包裹 launch、async

一,例子一

代码:

        //处理按钮点击事件
        binding.button1.setOnClickListener {
            runBlocking {
                try {
                    launch {
                        delay(100L)
                        1 / 0 // 故意制造异常
                    }
                } catch (e: ArithmeticException) {
                    println("Catch: $e")
                }

                delay(500L)
                println("End")
            }
        }

运行结果:崩溃,未捕捉到异常

image

二,例子二

代码:

        //处理按钮点击事件
        binding.button2.setOnClickListener {
            runBlocking {
                var deferred: Deferred<Unit>? = null
                try {
                    deferred = async {
                        delay(100L)
                        1 / 0
                    }
                } catch (e: ArithmeticException) {
                    println("Catch: $e")
                }

                deferred?.await()

                delay(500L)
                println("End")
            }
        }

运行结果:崩溃,未捕捉到异常

image

三,改进,针对launch

捕捉不到异常的原因:
当协程体当中的“1/0”执行的时候,我们的程序已经跳出 try-catch 的作用域了

代码:

        //处理按钮点击事件
        binding.button3.setOnClickListener {
            runBlocking {
                launch {
                    try {
                        delay(100L)
                        1 / 0 // 故意制造异常
                    } catch (e: ArithmeticException) {
                        println("Catch: $e")
                    }
                }

                delay(500L)
                println("End")
            }
        }

说明:解决方法就是:
我们把 try-catch 挪到 launch{} 协程体内部。
这样一来,它就可以正常捕获到 ArithmeticException 这个异常了

运行结果:

image

四,改进:针对async

代码:

        //处理按钮点击事件
        binding.button4.setOnClickListener {
            runBlocking {
                var deferred: Deferred<Unit>? = null

                deferred = async {
                    try {
                        delay(100L)
                        1 / 0
                    } catch (e: ArithmeticException) {
                        println("Catch: $e")
                    }
                }

                deferred?.await()

                delay(500L)
                println("End")
            }
        }

说明:

把 try-catch 挪到了 async{} 协程体内部,
这样可以正常捕获到 ArithmeticException 这个异常

运行结果:

image

 

posted @ 2025-08-02 15:06  刘宏缔的架构森林  阅读(6)  评论(0)    收藏  举报