Приостановка, пока StateFlow не достигнет одного из желаемых состояний, и возврат результата

Рассмотрим состояние закрытого класса.

      sealed class State {
    object Unknown : State()
    object Loading : State()
    object Success : State()
    data class Failure(val exception: Exception)
}

У меня есть поток состояний, в котором потребители могут активно слушать обновления состояния.

      val state:State = MutableStateFlow(State.Unknown)

Теперь я также хочу иметь простой метод приостановки, который ожидает, пока состояние не достигнет успеха или отказа, поэтому потребители, которым просто нужен результат один раз, не должны знать о потоке состояний.

Как этого добиться?

2 ответа

Хотя вы уже придумали рабочее решение, вы можете использовать встроенный Flow.first { ... } оператор для простоты.

      suspend fun waitForResult(): State  {
    val resultStates = setOf(State.Success::class, State.Failure::class)
    return state.first { it::class in resultStates }
}

Мне удалось придумать следующую функцию расширения, которая, похоже, работает нормально.

      suspend fun waitForResult(): State  {
    val resultStates = setOf(State.Success::class, State.Failure::class)
    return state.waitForStates(resultStates)
}

suspend fun <T : Any> StateFlow<T>.waitForStates(states: Set<KClass<out T>>): T = coroutineScope {
    var currentValue = value

    // not needed for correctness, just an optimisation
    if (currentValue::class in states) {
        return currentValue
    }

    coroutineScope {
        collect {
            if (it::class in states) {
                currentValue = it
                cancel()
            }
        }
    }

    return currentValue
}
Другие вопросы по тегам