原文:https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/
interface Flow
(source)
异步数据流,它顺序地发出值并正常或异常地完成。
流的中间运算符(例如 map, filter, take, zip 等)是应用于一个或多个上游流并返回下游流(可以在其中应用其他运算符)的函数。中间运算符不会在流中执行任何代码,并且自身不会挂起函数。它们只是建立了一连串的操作链,以便在将来执行并迅速返回。这被称为冷流特性。
流上的终端运算符要么是挂起功能,如 collect, single, reduce, toList 等,要么是在给定的 scope 内开始收集流的 launchIn 运算符。它们将应用于上游流并触发所有操作的执行。流的执行也称为收集流,并且始终以挂起的方式执行而实际没有阻塞。终端运算符是正常完成还是异常完成,取决于上游中所有流操作的执行成功或者失败。最基本的终端运算符就是 collect,例如:
try {
flow.collect { value ->
println("Received $value")
}
} catch (e: Exception) {
println("The flow has thrown an exception: $e")
}
默认情况下,流是顺序的,并且所有流操作都在同一协程中按顺序执行,除了一些专门设计用于将并发引入流执行的操作(例如 buffer 和 flatMapMerge)外。 有关详细信息,请参见其文档。
Flow 接口不携带信息,即关于该流是可以重复收集并在每次收集时触发执行相同代码的冷流,还是每次从同一个运行源收集时发出不同值的热流。 通常,流代表冷流,但是有一个 SharedFlow 子类型代表热流。 除此之外,任何流都可以通过 stateIn 和 shareIn 运算符转换为热流,或者通过 produceIn 运算符将流转换为热通道。
转载请说明出处:https://blog.csdn.net/hegan2010/article/details/113662541
创建流有以下几种基本方法:
Flow 接口的所有实现都必须遵守以下详细描述的两个关键属性:
这些属性确保了对流执行代码本地推理的能力,并使代码模块化,从而可以将上游流发送器与下游流收集器分开开发。 流的用户不需要知道其使用的上游流的实现细节。
流具有上下文保留属性:它封装了自己的执行上下文,并且从不向下游传播或泄漏它,因此使对特定转换或终端运算的执行上下文的推理变得微不足道。
仅有一种更改流上下文的方法:flowOn 运算符更改上游上下文(“ flowOn 运算符上方的所有内容”)。 有关其他信息,请参阅其文档。
这种推理可以在实例中得到示范:
val flowA = flowOf(1, 2, 3)
.map { it + 1 } // Will be executed in ctxA
.flowOn(ctxA) // Changes the upstream context: flowOf and map
// Now we have a context-preserving flow: it is executed somewhere but this information is encapsulated in the flow itself
val filtered = flowA // ctxA is encapsulated in flowA
.filter { it == 3 } // Pure operator without a context yet
withContext(Dispatchers.Main) {
// All non-encapsulated operators will be executed in Main: filter and single
val result = filtered.single()
myUi.text = result
}
从实现的角度来看,这意味着所有的流实现都应仅从同一个协程中发出值。 默认的流构建器有效地遵守了此约束。 如果流的实现未启动任何协程,则应使用流构建器。 它的实现可以避免大多数开发错误:
val myFlow = flow {
// GlobalScope.launch { // is prohibited
// launch(Dispatchers.IO) { // is prohibited
// withContext(CoroutineName("myFlow")) // is prohibited
emit(1) // OK
coroutineScope {
emit(2) // OK -- still the same coroutine
}
}
如果要将流的收集和发出分成多个协程,请使用 channelFlow。 它封装了所有的上下文保存工作,并允许您专注于特定于域的问题,而不是不变的实现细节。 可以在 channelFlow 中使用协程构建器的任何组合。
如果您正寻求高性能,并确保不会并发发出值和发生上下文跳转,那么可以将流构建器与 coroutineScope 或 supervisorScope 一起使用:
流的实现永远不会捕获或者处理下游流中发生的异常。 从实现的角度来看,这意味着永远不要将对 emit 和 emitAll 的调用包裹在 try {...} catch {...} 块中。 流中的异常处理应由 catch 运算符执行,并且旨在仅捕获来自上游流的异常,而传递所有下游异常。 类似地,终端运算符如 collect 会抛出在其代码或上游流中发生的任何未处理的异常,例如:
flow { emitData() }
.map { computeOne(it) }
.catch { ... } // catches exceptions in emitData and computeOne
.map { computeTwo(it) }
.collect { process(it) } // throws exceptions from process and computeTwo
可以对 onCompletion 运算符应用相同的推理,这是对 finally 块的声明性替换。
不遵守异常透明性要求可能会导致奇怪的行为,使得代码难以推理,因为 collect {...} 中的异常可能以某种方式被上游流“捕获”,从而限制了对代码的本地推理的能力。
流机制在运行时强制执行异常透明性,如果在上一次尝试中已经引发了异常,则在任何尝试发出值时都会引发 IllegalStateException。
Flow 符合 Reactive Streams,您可以使用 kotlinx-coroutines-reactive 模块中的 Flow.asPublisher 和 Publisher.asFlow 安全地将其与反应式流互操作。
Flow 接口对于第三方库中的继承不稳定, 因为将来可能会向该接口添加新方法,但在使用时会保持稳定。 使用 flow {...} 构建器函数创建一个实现。
collect |
Accepts the given collector and emits values into it. This method should never be implemented or used directly. 接受给定的收集器并向其中发出值。 永远不要实现或直接使用此方法。 |
broadcastIn |
Creates a broadcast coroutine that collects the given flow. 创建收集指定流的广播协程。 |
buffer |
Buffers flow emissions via channel of a specified capacity and runs collector in a separate coroutine. 缓冲流通过指定容量的通道进行发出,并在单独的协程中运行收集器。
|
cache |
|
cancellable |
Returns a flow which checks cancellation status on each emission and throws the corresponding cancellation cause if flow collector was cancelled. Note that flow builder and all implementations of SharedFlow are cancellable by default. 返回一个流,该流检查每个发出的取消状态,如果取消了流收集器,则抛出相应的取消原因。 请注意,流构建器和 SharedFlow 的所有实现默认都是可以取消的。 |
catch |
Catches exceptions in the flow completion and calls a specified action with the caught exception. This operator is transparent to exceptions that occur in downstream flow and does not catch exceptions that are thrown to cancel the flow. 在流完成过程中捕获异常,对捕获的异常调用指定的操作。 该运算符对下游流中发生的异常透明,并且不会捕获为取消流而抛出的异常。 |
collect |
Terminal flow operator that collects the given flow but ignores all emitted values. If any exception occurs during collect or in the provided flow, this exception is rethrown from this method. 流终端运算符,它收集给定的流但忽略所有发出的值。 如果在收集期间或者在提供的流中发生任何异常,则从此方法重新抛出此异常。
Terminal flow operator that collects the given flow with a provided action. If any exception occurs during collect or in the provided flow, this exception is rethrown from this method. 流终端运算符,通过提供的 |
collectIndexed |
Terminal flow operator that collects the given flow with a provided action that takes the index of an element (zero-based) and the element. If any exception occurs during collect or in the provided flow, this exception is rethrown from this method. 流终端运算符,它使用提供的 |
collectLatest |
Terminal flow operator that collects the given flow with a provided action. The crucial difference from collect is that when the original flow emits a new value, action block for previous value is cancelled. 流终端运算符,通过提供的 |
combine |
Returns a Flow whose values are generated with transform function by combining the most recently emitted values by each flow. 返回一个流,其值是通过组合每个流最近发出的值并使用转换函数生成的。 |
combineLatest |
|
combineTransform |
Returns a Flow whose values are generated by transform function that process the most recently emitted values by each flow. 返回一个流,其值由转换函数生成,该转换函数处理每个流最近发出的值。 |
conflate |
Conflates flow emissions via conflated channel and runs collector in a separate coroutine. The effect of this is that emitter is never suspended due to a slow collector, but collector always gets the most recent value emitted. 通过合并通道合并流发出,并在单独的协程中运行收集器。 这样做的结果是,发射器永远不会由于收集器速度较慢而挂起,并且收集器总是获得最新的发出值。 |
count |
Returns the number of elements in this flow.
Returns the number of elements matching the given predicate. 返回与给定 predicate 相匹配的元素数量。 |
debounce |
Returns a flow that mirrors the original flow, but filters out values that are followed by the newer values within the given timeout. The latest value is always emitted.
Returns a flow that mirrors the original flow, but filters out values that are followed by the newer values within the given timeout. The latest value is always emitted. 返回一个镜像原始流的流,但在给定的超时时间内过滤掉超时开始时的值的之后值。 始终会发出最新值。 |
distinctUntilChanged |
Returns flow where all subsequent repetitions of the same value are filtered out.
Returns flow where all subsequent repetitions of the same value are filtered out, when compared with each other via the provided areEquivalent function. 当通过提供的 areEquivalent 函数相互比较时,返回过滤掉一个值的所有后续重复值的流。 |
distinctUntilChangedBy |
Returns flow where all subsequent repetitions of the same key are filtered out, where key is extracted with keySelector function. 返回流,其中过滤掉使用 keySelector 函数提取出的键的所有后续重复键。 |
drop |
Returns a flow that ignores first count elements. Throws IllegalArgumentException if count is negative. 返回忽略开头 count 个元素的流。 如果 count 为负数,则抛出 IllegalArgumentException。 |
dropWhile |
Returns a flow containing all elements except first elements that satisfy the given predicate. 返回包含除满足给定 或翻译:返回包含不满足给定 |
filter |
Returns a flow containing only values of the original flow that matches the given predicate. 返回仅包含原始流中与给定 |
filterIsInstance |
Returns a flow containing only values that are instances of specified type R. 返回仅包含作为指定类型 R 的实例的值的流。 |
filterNot |
Returns a flow containing only values of the original flow that do not match the given predicate. 返回仅包含原始流中与给定 |
filterNotNull |
Returns a flow containing only values of the original flow that are not null. 返回仅包含原始流中非 null 值的流。 |
first |
The terminal operator that returns the first element emitted by the flow and then cancels flow’s collection. Throws NoSuchElementException if the flow was empty. 此终端运算符返回流程发出的第一个元素,然后取消流的收集。 如果流为空,则抛出 NoSuchElementException。
The terminal operator that returns the first element emitted by the flow matching the given predicate and then cancels flow’s collection. Throws NoSuchElementException if the flow has not contained elements matching the predicate. 此终端运算符返回流发出的与给定 |
firstOrNull |
The terminal operator that returns the first element emitted by the flow and then cancels flow’s collection. Returns 此终端运算符返回流程发出的第一个元素,然后取消流的收集。 如果流为空,则返回 null。
The terminal operator that returns the first element emitted by the flow matching the given predicate and then cancels flow’s collection. Returns 此终端运算符返回流发出的与给定 |
flatMapConcat |
Transforms elements emitted by the original flow by applying transform, that returns another flow, and then concatenating and flattening these flows. 通过应用转换函数来转换原始流发出的元素,返回另一个流,然后将这些流串联并展平。 |
flatMapLatest |
Returns a flow that switches to a new flow produced by transform function every time the original flow emits a value. When the original flow emits a new value, the previous flow produced by 每次原始流发出值时,返回一个流,该流为由转换函数产生的新流。 当原始流发出新值时,由转换块产生的先前流将被取消。 |
flatMapMerge |
Transforms elements emitted by the original flow by applying transform, that returns another flow, and then merging and flattening these flows. 通过应用转换函数来转换原始流发出的元素,返回另一个流,然后将这些流合并并展平。 |
flattenConcat |
Flattens the given flow of flows into a single flow in a sequentially manner, without interleaving nested flows. This method is conceptually identical to 将给定的流以顺序的方式展平为单个流,而不会交错嵌套的流。 该方法在概念上与 flattenMerge(concurrency = 1) 相同,但是实现速度更快。 |
flattenMerge |
Flattens the given flow of flows into a single flow with a concurrency limit on the number of concurrently collected flows. 将并发收集流,并发数限制在 |
flowOn |
Changes the context where this flow is executed to the given context. This operator is composable and affects only preceding operators that do not have its own context. This operator is context preserving: context does not leak into the downstream flow. 将执行此流的上下文更改为给定的上下文。 该运算符是可组合的,并且仅影响没有自己上下文的先前运算符。 此运算符是上下文保留的:上下文不会泄漏到下游流中。 |
flowWith |
The operator that changes the context where all transformations applied to the given flow within a builder are executed. This operator is context preserving and does not affect the context of the preceding and subsequent operations. 更改上下文的运算符,在该上下文中将执行在构建器中应用于给定流的所有转换。 此运算符是上下文保留的,并且不影响先前和后续运算符的上下文。 |
fold |
Accumulates value starting with initial value and applying operation current accumulator value and each element 从初始值开始累加值,然后对当前累加器值和每个元素应用 |
launchIn |
Terminal flow operator that launches the collection of the given flow in the scope. It is a shorthand for 流终端运算符,可在 scope 内启动给定流的收集。 它是 scope.launch { flow.collect() } 的简写。 |
map |
Returns a flow containing the results of applying the given transform function to each value of the original flow. 返回包含对原始流中的每个值应用给定的转换函数的结果的流。 |
mapLatest |
Returns a flow that emits elements from the original flow transformed by transform function. When the original flow emits a new value, computation of the transform block for previous value is cancelled. 返回一个流,该流发出从原始流中的元素通过 transform 函数转换得到的元素。 当原始流发出新值时,将取消对先前值的转换块的计算。 |
mapNotNull |
Returns a flow that contains only non-null results of applying the given transform function to each value of the original flow. 返回仅包含将给定的转换函数应用于原始流中的每个值的非 null 结果的流。 |
onCompletion |
Returns a flow that invokes the given action after the flow is completed or cancelled, passing the cancellation exception or failure as cause parameter of action. 返回在流完成或取消后调用给定的 |
onEach |
Returns a flow that invokes the given action before each value of the upstream flow is emitted downstream. 返回在上游流向下游流发出每个值之前调用给定的 |
onEmpty |
Invokes the given action when this flow completes without emitting any elements. The receiver of the action is FlowCollector, so 在此流完成却没有发出任何元素时调用给定的 |
onStart |
Returns a flow that invokes the given action before this flow starts to be collected. 返回在开始收集该流之前调用给定的 |
produceIn |
Creates a produce coroutine that collects the given flow. 创建一个 produce 协程来收集给定的流。 |
publish |
|
reduce |
Accumulates value starting with the first element and applying operation to current accumulator value and each element. Throws NoSuchElementException if flow was empty. 从第一个元素开始累加值,然后对当前累加器值与每个元素应用 |
replay |
|
retry |
Retries collection of the given flow up to retries times when an exception that matches the given predicate occurs in the upstream flow. This operator is transparent to exceptions that occur in downstream flow and does not retry on exceptions that are thrown to cancel the flow. 当上游流中出现与给定
|
retryWhen |
Retries collection of the given flow when an exception occurs in the upstream flow and the predicate returns true. The predicate also receives an 当上游流中发生异常并且 |
runningReduce |
Reduces the given flow with operation, emitting every intermediate result, including initial value. The first element is taken as initial value for operation accumulator. This operator has a sibling with initial value – scan. 通过 |
sample |
Returns a flow that emits only the latest value emitted by the original flow during the given sampling period. 返回在给定采样期间内只发出原始流的最新值的流。
Returns a flow that emits only the latest value emitted by the original flow during the given sampling period. 返回在给定采样期间内只发出原始流的最新值的流。 |
scan |
Folds the given flow with operation, emitting every intermediate result, including initial value. Note that initial value should be immutable (or should not be mutated) as it is shared between different collectors. For example: 通过 |
scanReduce |
|
shareIn |
Converts a cold Flow into a hot SharedFlow that is started in the given coroutine scope, sharing emissions from a single running instance of the upstream flow with multiple downstream subscribers, and replaying a specified number of replay values to new subscribers. See the SharedFlow documentation for the general concepts of shared flows. 将冷流转换为在给定协程 scope 内启动的热 SharedFlow,与多个下游订阅者共享上游流的单个运行实例的发出值,并向新订阅者重播指定数量的重播值。 有关共享流的一般概念,请参见 SharedFlow 文档。 |
single |
The terminal operator that awaits for one and only one value to be emitted. Throws NoSuchElementException for empty flow and IllegalStateException for flow that contains more than one element. 等待一个值并且仅有一个被发送值的终端运算符。 对于空流将引发 NoSuchElementException,对于包含多个元素的流将引发 IllegalStateException。 |
singleOrNull |
The terminal operator that awaits for one and only one value to be emitted. Returns the single value or 等待一个值并且仅有一个被发送值的终端运算符。 如果流为空或发出了多个值,则返回单个值或者 null。 |
stateIn |
Converts a cold Flow into a hot StateFlow that is started in the given coroutine scope, sharing the most recently emitted value from a single running instance of the upstream flow with multiple downstream subscribers. See the StateFlow documentation for the general concepts of state flows. 将冷流转换为在给定协程 scope 内启动的热 StateFlow,并与多个下游订阅者共享上游流的单个运行实例中最新发出的值。 有关状态流的一般概念,请参见 StateFlow 文档。
Starts the upstream flow in a given scope, suspends until the first value is emitted, and returns a hot StateFlow of future emissions, sharing the most recently emitted value from this running instance of the upstream flow with multiple downstream subscribers. See the StateFlow documentation for the general concepts of state flows. 在给定的协程 scope 内启动上游流,挂起直到发出第一个值,然后返回将来发出值的热 StateFlow,并与多个下游订阅者共享上游流的此运行实例的最新发出的值。 有关状态流的一般概念,请参见 StateFlow 文档。 |
switchMap |
|
take |
Returns a flow that contains first count elements. When count elements are consumed, the original flow is cancelled. Throws IllegalArgumentException if count is not positive. 返回包含开头 count 个元素的流。 当 count 个元素被消费完后,原始流将被取消。 如果 count 不是正数,则抛出 IllegalArgumentException。 |
takeWhile |
Returns a flow that contains first elements satisfying the given predicate. 返回包含满足给定 |
toCollection |
Collects given flow into a destination 将给定的流收集到一个 Collection。 |
toList |
Collects given flow into a destination 将给定的流收集到一个 List。 |
toSet |
Collects given flow into a destination 将给定的流收集到一个 Set。 |
transform |
Applies transform function to each value of the given flow. 将转换函数应用于给定流的每个值。 |
transformLatest |
Returns a flow that produces element by transform function every time the original flow emits a value. When the original flow emits a new value, the previous 每次原始流发出一个值时,返回一个通过转换函数产生元素的流。 当原始流发出新值时,先前的转换块将被取消,因此名称为 TransformLatest。 |
transformWhile |
Applies transform function to each value of the given flow while this function returns 只要转换函数返回 true 时,对于给定流的每个值应用转换函数(直到返回 false)。 |
withIndex |
Returns a flow that wraps each element into IndexedValue, containing value and its index (starting from zero). 返回一个将每个元素包装到 IndexedValue 中的流,其中包含值及其索引(从零开始)。 |
zip |
Zips values from the current flow ( 通过提供的转换函数将当前流(this)与其他流进行压缩,将转换函数应用于每对值。 一旦其中一个流完成,结果流就完成,并在剩余流上调用 cancel。 |
AbstractFlow |
Base class for stateful implementations of 流的状态实现的基类。 它会跟踪上下文保存所需的所有属性,如果违反任何属性,则抛出一个 IllegalStateException。 |
SharedFlow |
A hot Flow that shares emitted values among all its collectors in a broadcast fashion, so that all collectors get all emitted values. A shared flow is called hot because its active instance exists independently of the presence of collectors. This is opposed to a regular Flow, such as defined by the 一个热流,它以广播的方式在它的所有收集器之间共享发出值,以使所有的收集器都获得所有发出值。 共享流之所以称为热流,是因为其活跃实例独立于收集器的存在而存在。 这与普通流相反,常规流如 flow {...} 函数所定义,该流是冷流并针对每个收集器单独启动。 |