@@ -22,7 +22,7 @@ import kotlin.coroutines.*
22
22
* or [launchIn] operator that starts collection of the flow in the given scope.
23
23
* They are applied to the upstream flow and trigger execution of all operations.
24
24
* Execution of the flow is also called _collecting the flow_ and is always performed in a suspending manner
25
- * without actual blocking. Terminal operator complete normally or exceptionally depending on successful or failed
25
+ * without actual blocking. Terminal operators complete normally or exceptionally depending on successful or failed
26
26
* execution of all the flow operations in the upstream. The most basic terminal operator is [collect], for example:
27
27
*
28
28
* ```
@@ -37,10 +37,10 @@ import kotlin.coroutines.*
37
37
*
38
38
* By default, flows are _sequential_ and all flow operations are executed sequentially in the same coroutine,
39
39
* with an exception for a few operations specifically designed to introduce concurrency into flow
40
- * the execution such a [buffer] and [flatMapMerge]. See their documentation for details.
40
+ * execution such as [buffer] and [flatMapMerge]. See their documentation for details.
41
41
*
42
- * Flow interface does not carry information whether a flow is a truly a cold stream that can be collected repeatedly and
43
- * triggers execution of the same code every time it is collected or if it is a hot stream that emits different
42
+ * The ` Flow` interface does not carry information whether a flow truly is a cold stream that can be collected repeatedly and
43
+ * triggers execution of the same code every time it is collected, or if it is a hot stream that emits different
44
44
* values from the same running source on each collection. However, conventionally flows represent cold streams.
45
45
* Transitions between hot and cold streams are supported via channels and the corresponding API:
46
46
* [channelFlow], [produceIn], [broadcastIn].
@@ -54,27 +54,27 @@ import kotlin.coroutines.*
54
54
* * [flow { ... }][flow] builder function to construct arbitrary flows from
55
55
* sequential calls to [emit][FlowCollector.emit] function.
56
56
* * [channelFlow { ... }][channelFlow] builder function to construct arbitrary flows from
57
- * potentially concurrent calls to [send][kotlinx.coroutines.channels.SendChannel.send] function.
57
+ * potentially concurrent calls to the [send][kotlinx.coroutines.channels.SendChannel.send] function.
58
58
*
59
59
* ### Flow constraints
60
60
*
61
- * All implementations of `Flow` interface must adhere to two key properties that are described in detail below:
61
+ * All implementations of the `Flow` interface must adhere to two key properties described in detail below:
62
62
*
63
63
* * Context preservation.
64
64
* * Exception transparency.
65
65
*
66
66
* These properties ensure the ability to perform local reasoning about the code with flows and modularize the code
67
- * in such a way so that upstream flow emitters can be developed separately from downstream flow collectors.
68
- * A user of the flow does not needs to know implementation details of the upstream flows it uses.
67
+ * in such a way that upstream flow emitters can be developed separately from downstream flow collectors.
68
+ * A user of a flow does not need to be aware of implementation details of the upstream flows it uses.
69
69
*
70
70
* ### Context preservation
71
71
*
72
72
* The flow has a context preservation property: it encapsulates its own execution context and never propagates or leaks
73
73
* it downstream, thus making reasoning about the execution context of particular transformations or terminal
74
74
* operations trivial.
75
75
*
76
- * There is the only way to change the context of a flow: [flowOn][Flow.flowOn] operator,
77
- * that changes the upstream context ("everything above the flowOn operator").
76
+ * There is only one way to change the context of a flow: the [flowOn][Flow.flowOn] operator
77
+ * that changes the upstream context ("everything above the ` flowOn` operator").
78
78
* For additional information refer to its documentation.
79
79
*
80
80
* This reasoning can be demonstrated in practice:
@@ -97,7 +97,7 @@ import kotlin.coroutines.*
97
97
* ```
98
98
*
99
99
* From the implementation point of view, it means that all flow implementations should
100
- * emit only from the same coroutine.
100
+ * only emit from the same coroutine.
101
101
* This constraint is efficiently enforced by the default [flow] builder.
102
102
* The [flow] builder should be used if flow implementation does not start any coroutines.
103
103
* Its implementation prevents most of the development mistakes:
@@ -114,27 +114,27 @@ import kotlin.coroutines.*
114
114
* }
115
115
* ```
116
116
*
117
- * Use [channelFlow] if the collection and emission of the flow are to be separated into multiple coroutines.
117
+ * Use [channelFlow] if the collection and emission of a flow are to be separated into multiple coroutines.
118
118
* It encapsulates all the context preservation work and allows you to focus on your
119
119
* domain-specific problem, rather than invariant implementation details.
120
120
* It is possible to use any combination of coroutine builders from within [channelFlow].
121
121
*
122
- * If you are looking for the performance and are sure that no concurrent emits and context jumps will happen,
123
- * [flow] builder alongside with [coroutineScope] or [supervisorScope] can be used instead:
122
+ * If you are looking for performance and are sure that no concurrent emits and context jumps will happen,
123
+ * the [flow] builder can be used alongside a [coroutineScope] or [supervisorScope] instead:
124
124
* - Scoped primitive should be used to provide a [CoroutineScope].
125
125
* - Changing the context of emission is prohibited, no matter whether it is `withContext(ctx)` or
126
- * builder argument (e.g. `launch(ctx)`).
126
+ * a builder argument (e.g. `launch(ctx)`).
127
127
* - Collecting another flow from a separate context is allowed, but it has the same effect as
128
- * [flowOn] operator on that flow, which is more efficient.
128
+ * applying the [flowOn] operator to that flow, which is more efficient.
129
129
*
130
130
* ### Exception transparency
131
131
*
132
132
* Flow implementations never catch or handle exceptions that occur in downstream flows. From the implementation standpoint
133
133
* it means that calls to [emit][FlowCollector.emit] and [emitAll] shall never be wrapped into
134
134
* `try { ... } catch { ... }` blocks. Exception handling in flows shall be performed with
135
- * [catch][Flow.catch] operator and it is designed to catch only exception coming from upstream flow while passing
136
- * all the downstream exceptions. Similarly, terminal operators like [collect][Flow.collect]
137
- * throw any unhandled exception that occurs in its code or in upstream flows, for example:
135
+ * [catch][Flow.catch] operator and it is designed to only catch exceptions coming from upstream flows while passing
136
+ * all downstream exceptions. Similarly, terminal operators like [collect][Flow.collect]
137
+ * throw any unhandled exceptions that occur in their code or in upstream flows, for example:
138
138
*
139
139
* ```
140
140
* flow { emitData() }
@@ -143,13 +143,13 @@ import kotlin.coroutines.*
143
143
* .map { computeTwo(it) }
144
144
* .collect { process(it) } // throws exceptions from process and computeTwo
145
145
* ```
146
- * The same reasoning can be applied to [onCompletion] operator that is a declarative replacement for `finally` block.
146
+ * The same reasoning can be applied to the [onCompletion] operator that is a declarative replacement for the `finally` block.
147
147
*
148
- * Failure to adhere to the exception transparency requirement would result in strange behaviours that would make
148
+ * Failure to adhere to the exception transparency requirement can lead to strange behaviors which make
149
149
* it hard to reason about the code because an exception in the `collect { ... }` could be somehow "caught"
150
- * by the upstream flow, limiting the ability of local reasoning about the code.
150
+ * by an upstream flow, limiting the ability of local reasoning about the code.
151
151
*
152
- * Currently, flow infrastructure does not enforce exception transparency contracts, however, it might be enforced
152
+ * Currently, the flow infrastructure does not enforce exception transparency contracts, however, it might be enforced
153
153
* in the future either at run time or at compile time.
154
154
*
155
155
* ### Reactive streams
@@ -162,18 +162,18 @@ public interface Flow<out T> {
162
162
* Accepts the given [collector] and [emits][FlowCollector.emit] values into it.
163
163
* This method should never be implemented or used directly.
164
164
*
165
- * The only way to implement flow interface directly is to extend [AbstractFlow].
166
- * To collect it into the specific collector, either `collector.emitAll(flow)` or `collect { ... }` extension
167
- * should be used. Such limitation ensures that context preservation property is not violated and prevents most
165
+ * The only way to implement the `Flow` interface directly is to extend [AbstractFlow].
166
+ * To collect it into a specific collector, either `collector.emitAll(flow)` or `collect { ... }` extension
167
+ * should be used. Such limitation ensures that the context preservation property is not violated and prevents most
168
168
* of the developer mistakes related to concurrency, inconsistent flow dispatchers and cancellation.
169
169
*/
170
170
@InternalCoroutinesApi
171
171
public suspend fun collect (collector : FlowCollector <T >)
172
172
}
173
173
174
174
/* *
175
- * Base class to extend to have a stateful implementation of the flow .
176
- * It tracks all the properties required for context preservation and throws [IllegalStateException]
175
+ * Base class for stateful implementations of `Flow` .
176
+ * It tracks all the properties required for context preservation and throws an [IllegalStateException]
177
177
* if any of the properties are violated.
178
178
*
179
179
* Example of the implementation:
0 commit comments