Kotlin中级——callbackFlow

callbackFlow

将监听外部(其他线程)的不定时回调转为Flow,并在Flow取消时同步取消监听

如下,是一个温度监听类,每隔1秒发送数据

复制代码
    interface TemperatureListener {
        fun onTemperatureChanged(value: Double)
    }

    class TemperatureSensor {
        private var listener: TemperatureListener? = null
        private var senderJob: Job? = null

        fun register(listener: TemperatureListener) {
            this.listener = listener
            println("传感器:开始监听")
            senderJob = CoroutineScope(Dispatchers.Default).launch {
                var temperature = 25.0
                while (isActive) {
                    delay(1_000)
                    listener.onTemperatureChanged(temperature)
                    temperature += 0.5
                }
            }
        }

        fun unregister() {
            senderJob?.cancel()
            senderJob = null
            listener = null
            println("传感器:停止监听")
        }
    }

若普通调用,需要自行注册和取消注册

复制代码
    @Test
    fun runCallbackExample() = runBlocking {
        println("------------------------------------------------------------------------------------------------------------------------------------------------------")

        val sensor = TemperatureSensor()
        val listener = object : TemperatureListener {
            override fun onTemperatureChanged(value: Double) {
                println("普通回调收到温度:$value")
            }
        }

        sensor.register(listener)
        delay(2_100)
        sensor.unregister()

        println("------------------------------------------------------------------------------------------------------------------------------------------------------")
    }

传感器:开始监听
普通回调收到温度:25.0
普通回调收到温度:25.5
传感器:停止监听

如下新增扩展函数,将监听过程转为Flow,可以流式处理,并绑定相关生命周期

复制代码
    fun TemperatureSensor.temperatureFlow(): Flow<Double> = callbackFlow {
        val listener = object : TemperatureListener {
            override fun onTemperatureChanged(value: Double) {
                trySend(value)
            }
        }

        register(listener)

        // collect 被取消时,注销传感器监听
        awaitClose {
            unregister()
        }
    }

    @Test
    fun runCallbackFlowExample() = runBlocking {
        println("------------------------------------------------------------------------------------------------------------------------------------------------------")

        val sensor = TemperatureSensor()
        val collectJob = launch {
            sensor.temperatureFlow().collect { temperature ->
                println("收到温度:$temperature")
            }
        }

        // 收集两次每隔 1 秒发送的温度
        delay(2_100)
        collectJob.cancelAndJoin()

        // 取消 collect 后,awaitClose 会调用 sensor.unregister()
        println("------------------------------------------------------------------------------------------------------------------------------------------------------")
    }

传感器:开始监听
收到温度:25.0
收到温度:25.5
传感器:停止监听
相关推荐
三小河11 分钟前
SWC 凭什么比 Babel 快 ?项目优化迁移踩坑记录
前端·后端
zh_xuan14 分钟前
kotlin常见面试题
开发语言·kotlin·面试题
再吃一根胡萝卜30 分钟前
不改一行官方源码:用一个插件把 DeepSeek Harness 换成「平安one」
前端
mmsx33 分钟前
耳切法切带洞多边形:论文能跑通,真实数据为什么崩
android·kotlin
涛涛ing44 分钟前
2026年,你选的不再是框架,是渲染模型
前端
知守观1 小时前
同一个团队两套分包:DDD 四层落地后,domain 层最大的类还是 5885 行
java·后端·领域驱动设计
AiMan1 小时前
Perplexity还是不可导出左侧所有对话,只能单条内容,方法不对吗
前端
文丑颜不良啊1 小时前
LeetCode2541~2560题目解析
java·leetcode
AiMan1 小时前
千问生成的内容能否下载吗?
前端