Day29:复习 Channel、Flow

Coroutine 中如果要执行非同步程序,则需要把耗时任务写在 suspend 函式中,并且在一个 CoroutineScope 中来执行,而建立 CoroutineScope 的方式则是可以使用 launch、async。

如果我们有很多 suspend 函式想要同时开始执行,并且我们希望能够在执行的时候能够按照顺序产出结果, Coroutine 提供了两种方法,一种为 Channel ,另一种则是 Flow。

Channel

我们在 CoroutineScope 中使用 Channel ,并且使用 send() 来将获得的值传出去。在 Channel 的另一头,也就是接收端,我们使用 receive() 来接收由 send() 传送出来的值。

我们使用 Channel 的时机点是在我们有多个 suspend 函式想要执行,并且我们希望在其他的 CoroutineScope 接收这个值。

如同前面所说,Channel 是一种有顺序的传送方式,它的顺序是采取先进先出(FIFO),当我们使用 send() 将某个值传进 Channel 中时,在另一个 CoroutineScope 中呼叫 receive() 就会将该值取出。如果有多个值依序呼叫 send(),那麽在另外一头呼叫 receive() 时就会按照顺序出来,这边需要注意的是,呼叫 receive() 的次数必须要与 send() 相同,不然该 Channel 就会一直 suspend ,直到正确数量的 receive() 被呼叫。

Channel 提供了多种存放方式:

  • RENDEZVOUS
  • CONFLATED
  • UNLIMITED
  • BUFFERED
  • 其他

预设是 RENDZVOUS,是一种没有 buffer的 channel,使用这种 channel 必须要成双成对,也就是说呼叫 send() 就必须要呼叫 receive()。

CONFLATED 则是 buffer 大小只有一个,所以後面新的值就会把旧的值给盖掉。

UNLIMITED 则是有无限容量的 channel,所以呼叫 send() 的时候不会因为 buffer 的容量满了而让後面还没有执行的 send() 被 suspend。

BUFFERED 则是可以根据我们的需求给予固定大小的 buffer,当buffer 满了的时候,就会suspend send() 函式。

Flow

与 Channel 不同,Flow 是属於 code stream,也就是说 flow 只有当呼叫 terminal operator 的时候,才会执行,而在 terminal operator 之前,可以有多个 Intermediate operator (中间运算子),我们可以利用这中间运算子将这些值在输出之前改变其样貌。

要怎麽把值放入 flow 中呢?我们使用 emit() 将值射入 flow 中,并使用 collect 将全部的值取出。如我们前面所说的,我们可以运用中间运算子进行数值的处理,最後才使用终端运算子把结果取出。而这边的终端运算子不只有 collect。

我们可以使用 flowOn 来使用不同的 Dispatchers,选择不同的执行绪。

SharedFlow 以及 StateFlow

另外,有两种特殊的 flow,一个为 SharedFlow,另一个则是 StateFlow。

这两种 Flow 与原本的 Flow 不同,它们是属於 hot stream。

用处是什麽呢?如果我们希望把 Flow 的值同时通知给其他使用者,我们就可以使用。有两种方式使用,一种是将原本的 Flow 直接经过转换变成 SharedFlow 或是 StateFlow,另一种方式则是使用 MutableXXXFlow的版本,来将值填入,再将 MutableXXXFlow 转成 XXXFlow,那麽我们只要更新 MutableXXXFlow,其他使用者调用 XXXFlow 的 collect,就可以把值取出。

而根据 Flow 保存的值的方式不同,有分这两种 Flow,主要的区别在於 SharedFlow 可以有比较大的 buffer,所以可以存放比较多的内容,当有新的用户加入时,就可以把最新的资料都倒给它,相对的,StateFlow 则是 buffer 的容量只有 一,也就是说每次的新值加入时,都会把原本的值盖掉,而新的用户加入时,也只会得到最新的一笔资料。所以在 Android 的使用上会被提出用来更换 LiveData。


好了,Channel 以及 Flow 的复习到这边就差不多了,如果有问题可以看看前面的文章,或是可以跟我讨论 XD

那麽本篇就到这边告一段落了。

特别感谢

Kotlin Taiwan User Group

Kotlin 读书会


<<:  卡夫卡的藏书阁【Book20】- Kafka - KafkaJS 消费者 2

>>:  成为工具人应有的工具包-19 ProduKey

Day1 30天学会React,其实一点都不难

Hi! 时光飞逝,又过了一年,我又来自虐了,距离上次绞尽脑汁生出铁人赛文章也有一年多的时间了 废话,...

Google Cloud SDK

安装SDK 要使用Google云端首先起手式SDK,古人说工欲善其事必先利其器的道理告诉了我们可以先...

@Day30 | C# WixToolset + WPF 帅到不行的安装包 [最终回]

哈哈, 其实拖了很久了! 今天来把最後剩下功能给补齐,修复跟移除, 只是我在看InstallView...

【PHP 设计模式大头菜】模板方法 Template Method

模板方法 Template Method 模板方法,是一种如果这包水泥我有、你也有,就连乔瑟夫都有...

【零基础成为 AI 解梦大师秘笈】Day30 - Django 整合部署 AI model

AI 解梦最终秘笈 前言 系列文章简介 大家好,我们是 AI . FREE Team - 人工智慧自...