Kotlin Flow 数据流

86 阅读2分钟

Kotlin Flow 数据流

  • Flow
  • SharedFlow
  • StateFlow Flow 的设计灵感也来源于响应式流以及其各种实现。但是 Flow 的主要目标是拥有尽可能简单的设计,以及对kotlin协程更友好的支持 但从概念上讲,Flow 依然是响应式流。和RxJava类似,依然有冷热流之分。相比于RxJava的切换线程,Flow也会更加简单。

Flow

  • Flow 是一个接口,有一个 collect 的挂起函数,传递一个 FlowCollector 接口
  • 冷流、冷数据流:每一次流的收集都是已知的数据,collect 收集完以后就会立即销毁,不能在后续的使用中,如果后续需要发射新的值到该流中,无法再次收集,只能再调用一次 collect 进行收集
public interface Flow<out T> {

    /**
     * Accepts the given [collector] and [emits][FlowCollector.emit] values into it.
     *
     * This method can be used along with SAM-conversion of [FlowCollector]:
     * ```
     * myFlow.collect { value -> println("Collected $value") }
     * ```
     *
     * ### Method inheritance
     *
     * To ensure the context preservation property, it is not recommended implementing this method directly.
     * Instead, [AbstractFlow] can be used as the base type to properly ensure flow's properties.
     *
     * All default flow implementations ensure context preservation and exception transparency properties on a best-effort basis
     * and throw [IllegalStateException] if a violation was detected.
     */
    public suspend fun collect(collector: FlowCollector<T>)
}

FlowCollector

  • FlowCollector 是一个接口,有一个 emit 的挂起函数
/**
 * [FlowCollector] is used as an intermediate or a terminal collector of the flow and represents
 * an entity that accepts values emitted by the [Flow].
 *
 * This interface should usually not be implemented directly, but rather used as a receiver in a [flow] builder when implementing a custom operator,
 * or with SAM-conversion.
 * Implementations of this interface are not thread-safe.
 *
 * Example of usage:
 *
 * ```
 * val flow = getMyEvents()
 * try {
 *     flow.collect { value ->
 *         println("Received $value")
 *     }
 *     println("My events are consumed successfully")
 * } catch (e: Throwable) {
 *     println("Exception from the flow: $e")
 * }
 * ```
 */
public fun interface FlowCollector<in T> {

    /**
     * Collects the value emitted by the upstream.
     * This method is not thread-safe and should not be invoked concurrently.
     */
    public suspend fun emit(value: T)
}

flow

  • flow 方法会返回一个 SafeFlow 类的对象,SafeFlow 类继承 AbstractFlow 抽象类,AbstractFlow 实现了 Flow, CancellableFlow 两个接口
public fun <T> flow(@BuilderInference block: suspend FlowCollector<T>.() -> Unit): Flow<T> = SafeFlow(block)

asFlow

  • asFlow 是扩展函数,里面调用 flow 函数创建 Flow 的

flowOf

  • flowOf 里面也是调用 flow 函数来创建 Flow 的

线程调度

  • flowOn 是 Flow 的扩展函数 flowOn可以将执行此流的上下文更改为指定的上下文。 flowOn可以进行组合使用。 flowOn只影响前面没有自己上下文的操作符。已经有上下文的操作符不受后面flowOn影响。 不管flowOn如何切换线程,collect始终是运行在调用它的协程调度器上。

Flow 操作符

过度操作符 流程操作符

  • onStart 在上游流启动之前被调用
  • onEach 在上游流的每个值被下游发出之前调用
  • onCompletion 在流程完成或取消后调用,并将取消异常或失败作为操作的原因参数传递

异常操作符

  • catch

转换操作符

  • transform
  • map
  • fliter
  • zip

限制操作符

  • take
  • drop

末端操作符

  • collect

  • toList

SharedFlow 和 StateFlow

  • 都是可观察的数据容器类
  • MutableStateFlow 和 MutableSharedFlow

SharedFlow

  • SharedFlow 是一个接口,继承自 Flow,重写 collect 函数,有一个名叫 replayCache 的 List
public interface SharedFlow<out T> : Flow<T> {
    /**
     * A snapshot of the replay cache.
     */
    public val replayCache: List<T>

    /**
     * Accepts the given [collector] and [emits][FlowCollector.emit] values into it.
     * To emit values from a shared flow into a specific collector, either `collector.emitAll(flow)` or `collect { ... }`
     * SAM-conversion can be used.
     *
     * **A shared flow never completes**. A call to [Flow.collect] or any other terminal operator
     * on a shared flow never completes normally.
     *
     * @see [Flow.collect] for implementation and inheritance details.
     */
    override suspend fun collect(collector: FlowCollector<T>): Nothing
}

StateFlow

  • StateFlow 是一个接口,继承自 SharedFlow,重写 collect 函数,有一个名叫 replayCache 的 List

shareIn

  • Flow 的扩展函数