Day23:Hot Flow - StateFlow

State Flow 是从 Shared Flow 继承而来的,跟 Shared Flow 不同的地方在於它是有初始值的,至少会重播一个值给订阅者,所以它最少会记得一个值。

这边的值,就代表储存的状态 (State),所以我们如果要在多个订阅者中发送状态,我们就可以使用 State Flow。

既然是继承 Shared flow,那麽它也是 Hot flow,也不会自己停下来。在 State 中有一个可以更新的 value ,这个值就是实际 State 的值。

class Day23 {
    private val _state = MutableStateFlow(false)
    val state = _state.asStateFlow()

    suspend fun updateResult(value: Boolean) {
        delay(200)
        _state.update { value }
    }
}

在这个类别中,我们一样采用的是限制在这个类别里更新,让 MutableStateFlow 负责更新,对外只有让外面的使用者使用 StateFlow ,而这边的 StateFlow 我们是使用 MutableStateFlow 的 asStateFlow() 来将 MutableStateFlow 转换成 StateFlow。
而另外我们建立一个函式 updateResult可以更新 MutableStateFlow 的值,其中更新 MutableStateFlow 值的方式是使用 update{}

update 函式的内容我们来看一下

public inline fun <T> MutableStateFlow<T>.update(function: (T) -> T) {
    while (true) {
        val prevValue = value
        val nextValue = function(prevValue)
        if (compareAndSet(prevValue, nextValue)) {
            return
        }
    }
}

在这个函式中我们注意到它会一直执行带进来的 lambda,并将 lambda 的回传值作为 nextValue ,当现在的值以及 nextValue 相同时,就会跳出这个无穷回圈,否则将会一直在这个回圈里更新现在的值。

所以我们知道,当更新 StateFlow 的 value 时,如果 value 已经与现在的 value 一样,那麽就不会再次写入,也就是説,当现在的状态与更新状态一样时,就不会有任何动作。

执行它看看:

fun main() = runBlocking {
    val day23 = Day23()
    val state1 = day23.state

    state1.collect {
        println("$it")
        day23.updateResult(true)
    }
    println("done")
}
false
true

→ 由结果我们可以得知,collect 会一直去监听 StateFlow 的状态值,当状态有改变的时候,就会立即跑进 collect 这个 lambda 中,接着就会继续等待,因为它是一个 Hot Flow。所以 "done" 在这个例子下就永远都不会被呼叫了。

--请接续下篇--


<<:  Day13# defer

>>:  Day16-D3 的 Brush 刷子

DAY 26 制作表格-生成表格

上篇加入了支持中文的字体,这边使用matplotlib.pyplot与资料库资料生成表格 生成表格 ...

视觉化当日趋势图(2)-client端设定档&&建立controller、service

今天要来写JAVA的设定档, 首先找到路径:\ShioajiClient\src\main\reso...

Day26 - HTML 与 CSS (8) - 背景图片

背景图片 background-image:使用 url(pic路径) 来显示图片 backgrou...

D17 第八周 前端基础串 API

这礼拜的课程进度: FE102 中场休息到结束 FE102 後半段笔记摘要 介绍网页储存资料的方式 ...

Day 22 : 案例分享(7.1) 库存与制造 - 库存移动(调拨)流程

案例说明及适用场景 库存是odoo中很特别的功能或流程 单纯以功能的思考核心有二个,复式库存及推拉规...