Kotlin协程之flow工作原理

本文详细探讨了Kotlin协程中的flow工作原理,从创建flow、collect方法、flowOn操作符等方面进行解析。重点讲解了flow如何在协程中切换线程,以及flowOn如何影响数据生产和接收的流程。通过示例代码分析了flowOn的实现机制,揭示了其在多层调用中的线程影响。
摘要由CSDN通过智能技术生成

概述

最近想学习一下 Kotlin 中 flow 的用法, Google 上搜了搜发现很多比较 RxJava 和 flow 的文章,其实我在实际业务中从来没有用过 RxJava, 倒不是因为它不好,而是…我一直傻傻不太会用 RxJava 的操作符,看不太懂,又一直没花时间(懒惰)去研究它那些操作符的原理,就一直不怎么敢用。这次看到了 flow, 想着还是先去了解了解它内部几个操作符的原理吧,不然用起来总是不太踏实。

需要注意的是 Flow 需要在协程中使用, 因此配合协程,可以方便地切线程。分析 flow 工作流程离不开协程的工作原理,关于 Kotlin 协程的解析可以参考下列文章:

首先看一下 Flow 接口的源码,内部只有一个 collect 方法:

public interface Flow<out T> {
    // 是一个 suspend 方法,意味着会挂起当前协程
    @InternalCoroutinesApi
    public suspend fun collect(collector: FlowCollector<T>)
}

public interface FlowCollector<in T> {
    // 数据的发射方
    public suspend fun emit(value: T)
}

flow {}

以下面代码为例,讲解 flow 工作的基本流程:

flow { emit(1) }.collect { println(it) }

首先看一下 flow {} 的源码:

public fun <T> flow(@BuilderInference block: suspend FlowCollector<T>.() -> Unit): Flow<T> = SafeFlow(block)

上面就是以 block 代码块为参数创建了一个 SafeFlow 对象,SafeFlow 实现了 Flow 接口,于是接着看其 collect 方法。

collect

除了一开始贴的实现 Flow 接口调用 collect 方法的方式, Kotlin 还提供了调用 collect 的两个扩展函数,最后都是调用的 fun collect(collector: FlowCollector<T>) 方法:

public suspend fun Flow<*>.collect(): Unit = collect(NopCollector)

public suspend inline fun <T> Flow<T>.collect(crossinline action: suspend (value: T) -> Unit): Unit =
    collect(object : FlowCollector<T> {
        override suspend fun emit(value: T) = action(value)
    })

于是我们接着上面的示例,看一下 SafeFlow.collect 方法:

private class SafeFlow<T>(private val block: suspend FlowCollector<T>.() -> Unit) : AbstractFlow<T>() {
    override suspend fun collectSafely(collector: FlowCollector<T>) {
        collector.block()
    }
}

// collect 方法在父类 AbstractFlow 中
public abstract class AbstractFlow<T> : Flow<T>, CancellableFlow<T> {
    public final override suspend fun collect(collector: FlowCollector<T>) {
        val safeCollector = SafeCollector(collector, coroutineContext)
        try {
            collectSafely(safeCollector)
        } finally {
            safeCollector.releaseIntercepted()
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值