You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在等待MutableStateFlow新值时挂起Kotlin协程?

如何在等待MutableStateFlow的目标值时挂起Kotlin协程?

问题背景

现有代码使用MutableStateFlow维护状态,其中一个协程每秒更新状态值,另一个协程通过轮询方式读取状态:

val state = MutableStateFlow<Int>(1)

launch(Dispatchers.Default) {
    var counter = 1
    while (true) {
        state.emit(counter++)
        delay(1000)
    }
}

launch(Dispatchers.Default) {
    while (state.value < 1000) {
        print(state.value)
        delay(250)
    }
}

当前输出为111122223333444...,期望输出为1234...。

实际业务场景中,需要在发送数据前等待连接状态变为IDLE,目前采用的轮询方式性能较差:

while (state.value != ConnectionState.IDLE) { delay(100) }

期望实现逻辑:

  • 先检查当前状态值,若为目标值则直接继续执行
  • 若不是目标值,挂起协程直到状态变化,再次检查,不符合则继续挂起等待

虽然可以通过Mutex实现类似逻辑,但希望使用官方/标准方案。

官方标准解决方案

利用StateFlow的collect方法(Flow核心特性),可以实现高效的状态监听,避免轮询的资源浪费。

解决基础示例问题

将轮询的协程改为监听StateFlow数据流,每次状态更新时执行逻辑:

val state = MutableStateFlow<Int>(1)

launch(Dispatchers.Default) {
    var counter = 1
    while (true) {
        state.emit(counter++)
        delay(1000)
    }
}

launch(Dispatchers.Default) {
    state.collect { value ->
        if (value >= 1000) return@collect
        print(value)
    }
}

此时输出为1234...,完全符合期望。

通用等待目标状态的扩展函数

针对业务场景中“等待状态满足指定条件”的需求,可封装扩展函数复用逻辑:

import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collect

suspend fun <T> StateFlow<T>.await(predicate: (T) -> Boolean): T {
    // 先检查当前值,满足条件直接返回,避免不必要挂起
    val current = value
    if (predicate(current)) {
        return current
    }
    // 挂起监听流,直到值满足条件
    return collect { value ->
        if (predicate(value)) {
            return@collect value
        }
    }
}

业务场景中的使用示例

// 假设ConnectionState是自定义状态枚举
enum class ConnectionState { IDLE, CONNECTED, DISCONNECTED }

val connectionState = MutableStateFlow(ConnectionState.CONNECTED)

// 发送数据的协程逻辑
launch(Dispatchers.IO) {
    // 等待状态变为IDLE
    connectionState.await { it == ConnectionState.IDLE }
    // 状态满足后执行写入数据操作
    writeDataToSocket()
}

方案优势

  • 完全基于Kotlin官方Flow API,符合协程设计规范
  • 无不必要的轮询和延迟,仅在状态变化时唤醒协程,性能更优
  • 代码简洁可复用,适配各种状态监听场景

内容的提问来源于stack exchange,提问作者Jan Vladimir Mostert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 02:25:58