我们为什么要用 flow?

作者: 像程序那样去思考 | 来源:发表于2022-06-01 21:40 被阅读0次

作者:不近视的猫链接

前言

首先,我们得明确 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 正在不断取代 Rx 系列的位置,成为主流。从未来的发展角度来看,学习 flow 同样是一种趋势。

总结原因:

  • 支持挂起,能够协程进行完美交互
  • 拥有众多操作符,能够方便完成各项功能
  • Kotlin + flow 成为未来的发展趋势

相关文章

  • 我们为什么要用 flow?

    作者:不近视的猫链接 前言 首先,我们得明确 flow 的适用场景,那便是类似播报机情况,每隔一段时间就播报一段相...

  • git flow

    为什幺要用git flow git flow 是一个分支管理的策略,使得版本库的演进变得简洁,主干清晰,各个分支各...

  • Flutter: Flow 九宫格

    Flow需要自己实现子widget的位置转换,在很多场景下首先要考虑的是Wrap是否满足需求。Flow主要用于一些...

  • Vue源码学习(一)之目录结构和构建

    flow 为什么使用 FlowJavaScript 是动态类型语言,因此使用 Flow 做静态类型检查,在编译期间...

  • Flow 了解一下

    为什么引入 Flow? Flow 是介于 LiveData 与 RxJava 之间的一个解决方案,它有以下特点: ...

  • 我们为什么要用rxjava?

    好久没有写技术性文章了。最近趁着工作不是特别忙,再一次拿出一些时间研究Rxjava。在研究的过程中,我发现自己进展...

  • 我们为什么要用研?

    引言:为什么一个项目经理&SM要学习和分享产品知识? 俗话说"一个脱离产品的项目经理不是好开发。。。。"^_^笔者...

  • 我们为什么要用springcloud?

    为什么要用springcloud? 在回答这个问题之前我们要了解什么是微服务架构,以及这些年系统架构的演变过程 什...

  • flow了解

    认识Flow - JS是动态性语言,所以要一些静态类型检查,而vue用了这个flow所以我们了解flow对我们源码...

  • flow.js

    flow是facebook开源的js静态类型检查工具 flow命令: flow init:启用flow, flow...

网友评论

    本文标题:我们为什么要用 flow?

    本文链接:https://www.haomeiwen.com/subject/tihfmrtx.html