我们为什么要用 flow

前言

首先,我们得明确 flow 的适用场景,那便是类似播报机情况,每隔一段时间就播报一段相似的内容。由此,假如我们不使用 flow 的情况下,那我们怎么解决这种问题?

  • List ❎
  • sequence ❎

为什么这么快否决它们?因为他们都是阻塞式的,每两个元素间隔的时间,都会阻塞相应的线程,所以就不过多进行说明。
而另外两个选项可以实现 flow 的效果,也就是可挂起式运行。

  • 回调
  • LiveData

回调

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        startDownloading { result -> println(result) }
    }

    private fun startDownloading(callBack: (String) -> Unit) {
        GlobalScope.launch(Dispatchers.IO) {
            callBack("开始下载")
            delay(100)
            callBack("进度为 33%")
            delay(100)
            callBack("进度为 66%")
            delay(100)
            callBack("进度为 100%")
            delay(100)
            callBack("下载完成")
        }
    }
}
I/System.out: 开始下载
I/System.out: 进度为 33%
I/System.out: 进度为 66%
I/System.out: 进度为 100%
I/System.out: 下载完成

LiveData

class MainActivity : AppCompatActivity() {

    val result = MutableLiveData<String>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        result.observe(this){ result ->
            println(result)
        }

        startDownloading()
    }

    private fun startDownloading() {
        GlobalScope.launch(Dispatchers.IO) {
            result.postValue("开始下载")
            delay(100)
            result.postValue("进度为 33%")
            delay(100)
            result.postValue("进度为 66%")
            delay(100)
            result.postValue("进度为 100%")
            delay(100)
            result.postValue("下载完成")
        }
    }
}

日志输出:

I/System.out: 开始下载
I/System.out: 进度为 33%
I/System.out: 进度为 66%
I/System.out: 进度为 100%
I/System.out: 下载完成

总结

em…回调,也就是观察者模式的代表,确实是可以实现类似的效果,同时,LiveData 也是可以实现相应的效果的。

另外,从声明周期的角度来看,回调的方式和 flow 的方式默认都是不支持声明周期结束时自动取消的,而 LiveData 是支持的。

这里我们来验证下 flow 默认有没有自动取消的机制:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        GlobalScope.launch {
            flow { delay(8000)
                emit(1)}.collect { value ->
                println("value -> $value")
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        println("onDestroy 已被执行")
    }

}

结果输出:

I/System.out: onDestroy 已被执行
I/System.out: value -> 1

em…这样看,那岂不是 LiveData 更胜一筹?那我们为什么还要用 flow,干脆直接用 LiveData 就算了?

当然,LiveData 是不能替代 flow 的,因为他们原本就是不同赛道的东西,只不过碰巧 LiveData 能够实现这种异步刷新的功能而已。

另外,正如为什么之前 Rx 系列这么火的原因?并不是他们 Rx 系列能够提供类似回调的功能,而是他们拥有众多操作符,能够非常方便实现各种功能,而 flow 同样有这个优势,详情可以看看这篇「flow 操作符全解析」

现在 协程+ flow 正在不断取代 Rx 系列的位置,成为主流。从未来的发展角度来看,学习 flow 同样是一种趋势。

总结原因:

  • 支持挂起,能够协程进行完美交互
  • 拥有众多操作符,能够方便完成各项功能
  • Kotlin + flow 成为未来的发展趋势
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kotlin Flow 的 `debounce` 操作符用于限制 Flow 发射的频率,以便在指定的时间间隔内只发射最新的数据项。它通常用于处理用户输入或传感器数据等情况,以避免过多的数据处理或网络请求。 例如,假设你有一个搜索功能,用户在搜索框中输入关键字时会触发搜索操作。使用 `debounce` 可以确保只在用户停止输入一段时间后才执行搜索操作,避免频繁的搜索请求。这样可以减轻服务器负载并提供更好的用户体验。 下面是一个示例代码: ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import kotlin.system.measureTimeMillis fun main() = runBlocking { val searchFlow = flow { emit("k") delay(100) emit("ko") delay(100) emit("kot") delay(100) emit("kotl") delay(100) emit("kotlin") } val debouncedFlow = searchFlow .debounce(200) // 设置时间间隔为 200ms .onEach { query -> // 执行搜索操作 println("Searching for: $query") } .flowOn(Dispatchers.Default) val elapsedTime = measureTimeMillis { debouncedFlow.collect() } println("Total time: $elapsedTime ms") } ``` 在上面的示例中,`searchFlow` 表示用户输入的关键字流。通过使用 `debounce` 操作符,并设置时间间隔为 200ms,只有当用户停止输入超过 200ms 时,才会触发搜索操作。`onEach` 操作符用于处理每个发射的数据项,并执行搜索操作。最后,通过 `collect` 来收集 Flow 的数据。 运行示例代码,你会发现只有在用户停止输入一段时间后,才会执行搜索操作。这就是 `debounce` 操作符的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值