Kotlin Flow(一)

Kotlin Flow

What is a Flow in Kotlin?

It’s a Kotlin language feature that serves as a reactive programming framwork.

Flow 是 Google 官方提供的一套用于 kotlin 协程的响应式编程模型。Flow 数据流类似于生产者与消费者模式,不过可以在它们之间进行一些链式处理。

class MainViewModel : ViewModel() {

    val countDownFlow = flow<Int> {
        val startingValue = 10
        var currentValue = startingValue
        emit(currentValue)
        while (currentValue > 0) {
            delay(1000L)
            currentValue--
            emit(currentValue)
        }
    }

    init {
        collectFlow()
    }
    
    private fun collectFlow() {
        viewModelScope.launch {
            countDownFlow
                .collect { time ->
                    println("The current time is $time")
                }
        }
    }
}    

为什么说 Flow 是冷流呢?

在 countDownFlow 还没有被 collect 时,它是不会去 emit 数据的,只有当它被消费的时候,它才会 emit 生产数据。

Flow 常见的操作符

filter:过滤数据

map:可将数据映射成其他值

	private fun commonOperator() {
        viewModelScope.launch {
            countDownFlow
                .filter {
                    it % 2 == 0
                }
                .map {
                    it * it
                }
                .collect {
                    println("The value is $it")
                }
        }
    }

onEach:每次 emit 数据后,在收集到数据之前执行

    private fun collectFlow() {
        viewModelScope.launch {
            countDownFlow
            .onEach {
                println("the other each is $it")
            }
            .collect { time ->
                      println("The current time is $time")
            } // The collect only confirms the flow finished.
        }
    }
    private fun collectFlow() {
        countDownFlow
            .onEach {
                println("The value is $it")
            }
            .launchIn(ViewModelScope)
        // They are equivalent.
        countDownFlow
            .collect {
                println("The value is $it")
            }
    }

Terminal Operator

Why call them terminal operator?

Because they terminate the flow so these basically take the whole results of a flow all emissions together and then do something with these.

count:返回所有满足条件的数据个数

    private fun countOperator() {
        viewModelScope.launch {
            val count = countDownFlow
            .count {
            it % 2 == 0
            }
            println("The count is $count")
        }
    }

reduce:有两个参数(accumulator -> 上次所 collect 的数据,value -> 当前 collect 的数据)

	private fun reduceOperator() {
        viewModelScope.launch {
            val reduceResult = countDownFlow
                .reduce { accumulator, value ->
                    accumulator + value // 10 10+9 10+9+8 ...
                }
            println("The count is $reduceResult") // 10+9+...+1+0
        }
    }

fold:类似于 reduce,不同之处是多了一个初始值 initValue

	private fun foldOperator() {
        viewModelScope.launch {
            val reduceResult = countDownFlow
                .fold(100) { accumulator, value ->
                    accumulator + value
                }
            println("The count is $reduceResult") // 100+10+9+...+1+0
        }
    }

Flatten flows(If we have two flows then we can combine these to have the results coming in a single flow)

flatMapConcat:第一个 flow 必须等待第二个 flow 发送完数据之后,才会继续 emit 发送数据

	private fun flattenFlows() {
        val flow1 = flow {
            emit(1)
            delay(3000L)
            emit(2)
        }
        viewModelScope.launch {
            flow1.flatMapConcat { value ->
                flow {
                    emit(value + 3)
                    delay(1000L)
                    emit(value + 4)
                }
            }.collect {
                Log.d(TAG, "The value is $it")
            }
        }
    }

在这里插入图片描述

flatMapMerge:如果第二个 flow 还没有执行完第一个 flow 并不会等待,而是继续 emit 发送数据

	private fun flatMapMerge() {
        val flow1 = flow {
            emit(1)
            emit(3)
        }
        viewModelScope.launch {
            flow1.flatMapMerge { value ->
                flow {
                    emit(value + 3)
                    delay(1000L)
                    emit(value + 4)
                }
            }.collect {
                Log.d(TAG, "The value is $it")
            }
        }
    }

在这里插入图片描述

buffer:flow emit 数据不会等待 collect 结束后才继续 emit,而是持续 emit 数据,若消费者没来得及消费,那么就将产品放入仓库存储,当消费者需要消费时就直接从仓库获取。

	private fun restaurantBufferDemo() {
        val flow = flow {
            delay(500L)
            emit("Appetizer")
            delay(800L)
            emit("Main dish")
            delay(200L)
            emit("Dessert")
        }
        viewModelScope.launch {
            flow.onEach {
                println("FLOW: $it is delivered")
            }.buffer().collect {
                println("FLOW: Now eating $it")
                delay(3000L)
                println("FLOW: Finished eating $it")
            }
        }
    }

在这里插入图片描述

conflate:与 buffer 不同,仓库中只会存在最新的产品(emit 的数据),旧的产品(emit 的数据)直接丢弃。

private fun restaurantConflateDemo() {
        val flow = flow {
            delay(500L)
            emit("Appetizer")
            delay(800L)
            emit("Main dish")
            delay(200L)
            emit("Dessert")
        }
        viewModelScope.launch {
            flow.onEach {
                println("FLOW: $it is delivered")
            }.conflate().collect {
                println("FLOW: Now eating $it")
                delay(3000L)
                println("FLOW: Finished eating $it")
            }
        }
    }

在这里插入图片描述

collectLatest:生产者持续生产产品,消费者只会消费最新的产品,当又有新的产品时,消费者直接丢弃当前产品。

	private fun collectLatestDemo() {
        val flow = flow {
            delay(500L)
            emit("Appetizer")
            delay(800L)
            emit("Main dish")
            delay(200L)
            emit("Dessert")
        }
        viewModelScope.launch {
            flow.onEach {
                println("FLOW: $it is delivered")
            }.collectLatest {
                println("FLOW: Now eating $it")
                delay(3000L)
                println("FLOW: Finished eating $it")
            }
        }
    }

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值