使用 Kotlin 进行 Android 编程
by Pierre-Olivier Laurence, Amanda Hinchman-Dominguez, G. Blake Meike, Mike Dunn
第 10 章 流量 流量
本作品已使用人工智能进行翻译。欢迎您提供反馈和意见:translation-feedback@oreilly.com
到目前为止,我们已经介绍了例行程序、暂停函数,以及如何使用Channels 处理流。从上一章我们可以看到,使用Channels 意味着启动例行程序来发送和/或接收来自Channels 的信息。上述例行程序是热门实体,有时难以调试,或者如果没有在应该取消的时候取消,就会泄漏资源。
Flows 与Channels 一样,都是为了处理异步数据流,但抽象程度更高,使用的库工具也更好。从概念上讲,Flows 与Sequences 类似,只是Flow 的每一步都可以是异步的。在结构化并发中整合数据流也很容易,可避免资源泄漏。
但是,Flows1Channel Channel Channel仍适用于某些架构,如 CSP(参见第 9 章)。尽管如此,您会发现流适合异步数据处理中的大多数需求。
在本章中,我们将向你介绍冷流和热流。你将看到,当你想确保不泄漏任何资源时,冷流如何成为更好的选择。另一方面,热流有不同的用途,例如当你需要在应用程序中的实体之间建立 "发布-订阅 "关系时。例如,您可以使用热流实现事件总线。
了解流程的最佳方法是了解它们在实际应用中的使用情况。因此,本章还将介绍一系列典型用例。
流量简介
让我们使用Flow 重新实现例 9-6 :
funnumbers():Flow<Int>=flow{emit(1)emit(2)// emit other values}
有几个方面值得注意:
-
我们返回的不是
Channel实例,而是Flow实例。 -
在流程内部,我们使用
emit暂停函数,而不是send。 -
numbers函数返回一个Flow实例,它不是一个暂停函数。调用numbers函数本身并不会启动任何程序,它只是立即返回一个Flow实例。
总之,您可以在flow 块中定义排放值。调用numbers 函数时,该函数会快速返回一个Flow 实例,而不会在后台运行任何程序。
在消费网站上:
funmain()=runBlocking{valflow=numbers()flow.collect{println(it)}}

我们使用
numbers函数得到Flow的一个实例。
一旦我们得到了一个流,我们就不会再对其进行循环(就像使用通道那样),而是使用
collect函数,在流的术语中,它被称为 终端操作符。我们将在"操作符 "中扩展流操作符和终端操作符 ...