# Kotlin 系列之Flow (四)组合与完成

Hello I`am Flow Welcome to Flow Unit 4

这次来聊聊,Flow 的 组合完成

Flow 组合

顾名思义:就是将 flow 与 flow 组合起来执行

1 、zip 操作符

用过RxJava 的同学对 zip 一定不陌生吧

Flow 的 zip 的作用也几乎一致的

就是将 flowA 中的一个 emit 和 flowB 中对应的一个 emit 进行合并,再次做为结果传递给 终止操作

Example
fun main() = runBlocking<Unit>{
    val nums = (1..5).asFlow()
    val strs = flowOf("one","two","three","four","five")

    nums.zip(strs){ a,b -> "$a --- $b" }.collect{ println(it)}
}

结果打印:
        1 --- one
        2 --- two
        3 --- three
        4 --- four
        5 --- five

2 、combine 操作符

与 zip 不同的点在于,combine 会将 flowA 发射的 emit 与 flowB **最新发射 **的 emit 组合起来

fun main() = runBlocking {
  val flowA = (1..2).asFlow().onEach { delay(100)  }
  val flowB = flowOf("one","two").onEach { delay(220)  }
  flowA.combine(flowB) { a, b -> "$a and $b" }
      .collect { println(it) }
}

结果打印:
         2 and one  
         2 and two
//并没有 打印 “1” ,说明 flowA 发射的 “1”,完全错过了 flowB 的发射			
3、flatMapConcat 操作符

将嵌套的 flow 进行 “ 打平 ”,变成 单个流 执行

private fun myMethod(i:Int) = flow{
    emit("$i:First")
    delay(500)
    emit("$i:Second")
}

fun main()  = runBlocking<Unit>{
    var currentTimeMillis = System.currentTimeMillis()

    (1..3).asFlow().onEach { delay(100) }
        .flatMapConcat{ myMethod(it)}
        .collect {println("$it at ${System.currentTimeMillis() - currentTimeMillis}")  }
}

结果打印:
        1:First at 125
        1:Second at 629
        2:First at 733
        2:Second at 1236
        3:First at 1341
        3:Second at 1843

flow 完成

作为程序,一定会关心,它在什么时候执行完毕吧(嗯!要有SHI有ZHONG

有两种形式

1、try-finally

这种不用多说,地球人都知道(M蛋 这也算!~)

finally:俺不是故意的

private fun myMethod() = (1..10).asFlow()

fun main() = runBlocking{
    try {
        myMethod().collect { println(it) }
    }finally {
        println("执行完了!~") 
    }
}
2、onCompletion 中间操作符

优点:onComletion 有一个 cause:Throwable?的可空参数

可以根据 cause 是否为空,判断程序是否出现异常,方便我们去进行下一步操作 赞!

private fun myMethod() = flow{
    emit(1)
    throw RuntimeException()
}

fun main() = runBlocking{
    myMethod().onCompletion{ 
      cause ->if (cause != null) println("onCompletion Exceptionally")
    }
    .catch{ cause -> println("catch entered $cause")}
    .collect{ println(it)}
}
注意点:onCompletion 只能反应 上游出现的异常 ,不能反应 下游出现的异常

所以 应当与 try-finally 看情况使用

private fun myMethod() = (1..10).asFlow()

fun main() = runBlocking{
    myMethod().onCompletion{ cause ->if (cause != null) println("onCompletion Exceptionally")}
        .catch{ cause -> println("catch entered $cause")}
        .collect{ value ->
            check(value <= 1){
                "Collected $value"
            }
        }
}

异常处理

也是通过 try - catch 来处理,重点是 try - catch 可以捕获 Flow (发射阶段)、(中间操作)、下游(终止操作)的异常

/**
 *   try catch 可以捕获 Flow 三个阶段的 异常
 *   1 发射阶段
 *   2 中间操作阶段
 *   3 终止操作阶段
 */
private fun myMethod() =
    flow{
     for (i in 1..3){
         println("发射阶段 $i" )
         emit(i)
        }
     }.map{
         value->
        check(value <= 1){
            "Crash on $value"
        }
        "string $value"
    }

fun main() = runBlocking {
    try {
        myMethod().collect { println(it)}
    }catch (e: Throwable){
        println("Caught $e")
    }
}

小结:介绍了一些 Flow的 组合操作符 (zip 、combine、flatMapConcat) 完成环节(onCompletion 即注意事项)异常捕获 try catch 的作用范围

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值