Kotlin协程Flow的异常处理与完成处理

一、异常处理

1.收集(collect)的时候(下游)出现的异常

  • 使用 try-catch 块来捕获在收集流时可能抛出的异常(命令式)
   fun simpleFlow() = flow{
        for (i in 1..3){
            println("Emitting $i")
            emit(i)
        }
    }
    @Test
    fun testFlow1() = runBlocking<Unit> {
        try {
            simpleFlow().collect {value -> 
                println(value)
                check(value <= 1){"Collected $value"}//不符合会抛出异常
            }
        } catch (e : Throwable){
            println("Caught $e")
        }
    }

可见3并没有输出,因为在check(value <= 1){"Collected $value"}这一步发现了异常,用catch (e : Throwable)来进行捕获

2.在Flow构建的时候(上游)出现了异常

使用 catch 块来捕获在产生流时可能抛出的异常(声明式)

   @Test
    fun testFlow2() = runBlocking<Unit> {
        flow {
            emit(1)
            throw ArithmeticException("Div 0")
        }.catch { e: Throwable -> println("Caught $e") }
            .flowOn(Dispatchers.IO)
            .collect{println(it)}
    }

肯定有同学在疑惑为什么这样子做,使用catch和try-catch具体有什么区别,下面我来简单解释一下:

流的创建阶段:在流的创建阶段,使用 catch 操作符可以确保在流内部发生异常时进行处理。这样可以更好地控制流的行为,并在异常发生时采取适当的措施,例如日志记录、默认值提供等。就是说上流这种设计模式只是想捕获到异常然后更好的处理流上层的问题,比如 这段代码:捕获到了异常仍可以更新数据

流的收集阶段:在收集流的时候,使用 try-catch 块可以更灵活地处理异常。由于收集阶段是在调用流的地方,可能有不同的上下文和需求,因此在这里使用 try-catch 可以根据具体情况采取不同的异常处理策略。

 假如你使用try-catch的话,不仅臃肿,而且也没必要,不适合上层流构建的设计模式

更新的emit(10)直接报错了


二、Flow完成处理

finally (命令式):您可以在流的收集器中使用 finally 块来执行无论流是否正常完成或异常完成都需要执行的清理操作。finally 块中的代码将在流完成后执行,无论是正常完成还是异常完成。

onCompletion (声明式)onCompletion 操作符用于指定当流完成时要执行的操作。与 finally 块不同,onCompletion 操作符允许您访问到流完成时的异常信息(如果有的话),并且可以选择性地处理异常信息,简单来讲就是能抛出异常信息(上游下游都可以抛出),但不能捕获,要捕获的话需要使用catch(上游)或者try-catch(下游)->又和之前对应了

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Imagine8877

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值