Kotlin之SharedFlow和Stateflow

本文探讨了Kotlin中的SharedFlow和StateFlow。SharedFlow是一个hot stream,具有replay和extraBufferCapacity特性,影响着数据处理的挂起与溢出行为。通过示例代码展示了不同参数设置如何影响数据流动。相比之下,StateFlow具备防抖功能,当值未变化时不会触发新事件。源码分析揭示了StateFlow如何确保值更新时的高效处理。
摘要由CSDN通过智能技术生成

SharedFlow

SharedFlow是一个hot stream. sharedflow有以下特点:

  1. 没有默认值
  2. 可以保持旧值
  3. emit会挂起直到所有的订阅者处理完成
public fun <T> MutableSharedFlow(
    replay: Int = 0,
    extraBufferCapacity: Int = 0,
    onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND
)

replay: 重新发送给新订阅者之前值的个数

extraBufferCapacity:除了replay缓冲区个数之外的缓冲区的值。当有剩余空间的时候emit就不会挂起

onBufferOverflow:当extraBufferCapacity溢出时的处理。有下面三种处理方式:

public enum class BufferOverflow {
    /**
     * Suspend on buffer overflow.
     */
    SUSPEND,

    /**
     * Drop **the oldest** value in the buffer on overflow, add the new value to the buffer, do not suspend.
     */
    DROP_OLDEST,

    /**
     * Drop **the latest** value that is being added to the buffer right now on buffer overflow
     * (so that buffer contents stay the same), do not suspend.
     */
    DROP_LATEST
}

使用demo来测试这几个参数的作用:

1.测试replay的作用

fun `sharedflow Reply = 1`()= runBlocking{
    var sharedflow = MutableSharedFlow<Int>(replay = 1)
    GlobalScope.launch {
        sharedflow.emit(111)
        sharedflow.emit(222)
    }
    val job1 = GlobalScope.launch {
        delay(5000)
        sharedflow.collect{
            println("first job : $it")
        }
    }

    val job2 = GlobalScope.launch {
        delay(10000)
        sharedflow.collect{
            println("second job : $it")
        }
    }

    job1.join()
    job2.join()
}

结果:

first job : 222
second job : 222

上面的例子可以看出,设置了replay为1(默认为0),job1和job2最后打印的都是“222”

2.测试extraBufferCapacity的作用

fun `sharedflow emit suspend`() = runBlocking{
    var sharedflow = MutableSharedFlow<Int>()

    val job1 = GlobalScope.launch {
        sharedflow.collect{
            //println("${gettime()}:first job: $it")
        }
    }
    val job2 = GlobalScope.launch {
        sharedflow.collect{
            delay(5000)
            //println("${gettime()}:second job: $it")
        }
    }
    val job3 = GlobalScope.launch {
        for (i in 1..5){
            delay(500)
            println("${gettime()}:start--------emit $i")
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值