@@ -102,7 +102,7 @@ This code prints the numbers after waiting for a second.
102102### Flows
103103
104104Using the ` List<Int> ` result type, means we can only return all the values at once. To represent
105- the stream of values that are being asynchronously computed, we can use a [ ` Flow<Int> ` ] [ Flow ] type just like we would use the ` Sequence<Int> ` type for synchronously computed values:
105+ the stream of values that are being computed asynchronously , we can use a [ ` Flow<Int> ` ] [ Flow ] type just like we would use a ` Sequence<Int> ` type for synchronously computed values:
106106
107107``` kotlin
108108import kotlinx.coroutines.*
@@ -151,11 +151,11 @@ I'm not blocked 3
151151
152152Notice the following differences in the code with the [ Flow] from the earlier examples:
153153
154- * A builder function for [ Flow] type is called [ flow] [ _flow ] .
155- * Code inside the ` flow { ... } ` builder block can suspend.
156- * The ` simple ` function is no longer marked with ` suspend ` modifier.
157- * Values are _ emitted_ from the flow using [ emit] [ FlowCollector.emit ] function.
158- * Values are _ collected_ from the flow using [ collect] [ collect ] function.
154+ * A builder function of [ Flow] type is called [ flow] [ _flow ] .
155+ * Code inside a ` flow { ... } ` builder block can suspend.
156+ * The ` simple ` function is no longer marked with a ` suspend ` modifier.
157+ * Values are _ emitted_ from the flow using an [ emit] [ FlowCollector.emit ] function.
158+ * Values are _ collected_ from the flow using a [ collect] [ collect ] function.
159159
160160> We can replace [ delay] with ` Thread.sleep ` in the body of ` simple ` 's ` flow { ... } ` and see that the main
161161> thread is blocked in this case.
@@ -215,12 +215,12 @@ Flow started
215215<!-- - TEST -->
216216
217217This is a key reason the ` simple ` function (which returns a flow) is not marked with ` suspend ` modifier.
218- By itself, ` simple() ` call returns quickly and does not wait for anything. The flow starts every time it is collected,
219- that is why we see "Flow started" when we call ` collect ` again.
218+ The ` simple() ` call itself returns quickly and does not wait for anything. The flow starts afresh every time it is
219+ collected and that is why we see "Flow started" every time we call ` collect ` again.
220220
221221## Flow cancellation basics
222222
223- Flow adheres to the general cooperative cancellation of coroutines. As usual, flow collection can be
223+ Flows adhere to the general cooperative cancellation of coroutines. As usual, flow collection can be
224224cancelled when the flow is suspended in a cancellable suspending function (like [ delay] ).
225225The following example shows how the flow gets cancelled on a timeout when running in a [ withTimeoutOrNull] block
226226and stops executing its code:
@@ -268,13 +268,13 @@ See [Flow cancellation checks](#flow-cancellation-checks) section for more detai
268268
269269## Flow builders
270270
271- The ` flow { ... } ` builder from the previous examples is the most basic one. There are other builders for
272- easier declaration of flows:
271+ The ` flow { ... } ` builder from the previous examples is the most basic one. There are other builders
272+ that allow flows to be declared :
273273
274- * [ flowOf] builder that defines a flow emitting a fixed set of values.
275- * Various collections and sequences can be converted to flows using ` .asFlow() ` extension functions .
274+ * The [ flowOf] builder defines a flow that emits a fixed set of values.
275+ * Various collections and sequences can be converted to flows using the ` .asFlow() ` extension function .
276276
277- So , the example that prints the numbers from 1 to 3 from a flow can be written as:
277+ For example , the snippet that prints the numbers 1 to 3 from a flow can be rewritten as follows :
278278
279279``` kotlin
280280import kotlinx.coroutines.*
@@ -301,17 +301,18 @@ fun main() = runBlocking<Unit> {
301301
302302## Intermediate flow operators
303303
304- Flows can be transformed with operators, just as you would with collections and sequences.
304+ Flows can be transformed using operators, in the same way as you would transform collections and
305+ sequences.
305306Intermediate operators are applied to an upstream flow and return a downstream flow.
306307These operators are cold, just like flows are. A call to such an operator is not
307308a suspending function itself. It works quickly, returning the definition of a new transformed flow.
308309
309310The basic operators have familiar names like [ map] and [ filter] .
310- The important difference to sequences is that blocks of
311+ An important difference of these operators from sequences is that blocks of
311312code inside these operators can call suspending functions.
312313
313314For example, a flow of incoming requests can be
314- mapped to the results with the [ map] operator, even when performing a request is a long-running
315+ mapped to its results with a [ map] operator, even when performing a request is a long-running
315316operation that is implemented by a suspending function:
316317
317318``` kotlin
@@ -337,7 +338,7 @@ fun main() = runBlocking<Unit> {
337338>
338339 {type="note"}
339340
340- It produces the following three lines, each line appearing after each second :
341+ It produces the following three lines, each appearing one second after the previous :
341342
342343``` text
343344response 1
@@ -593,7 +594,7 @@ Since `simple().collect` is called from the main thread, the body of `simple`'s
593594This is the perfect default for fast-running or asynchronous code that does not care about the execution context and
594595does not block the caller.
595596
596- ### Wrong emission withContext
597+ ### A common pitfall when using withContext
597598
598599However, the long-running CPU-consuming code might need to be executed in the context of [ Dispatchers.Default] and UI-updating
599600code might need to be executed in the context of [ Dispatchers.Main] . Usually, [ withContext] is used
@@ -1012,8 +1013,8 @@ We get quite a different output, where a line is printed at each emission from e
10121013
10131014## Flattening flows
10141015
1015- Flows represent asynchronously received sequences of values, so it is quite easy to get in a situation where
1016- each value triggers a request for another sequence of values. For example, we can have the following
1016+ Flows represent asynchronously received sequences of values, and so it is quite easy to get into a situation
1017+ where each value triggers a request for another sequence of values. For example, we can have the following
10171018function that returns a flow of two strings 500 ms apart:
10181019
10191020``` kotlin
@@ -1026,23 +1027,23 @@ fun requestFlow(i: Int): Flow<String> = flow {
10261027
10271028<!-- - CLEAR -->
10281029
1029- Now if we have a flow of three integers and call ` requestFlow ` for each of them like this:
1030+ Now if we have a flow of three integers and call ` requestFlow ` on each of them like this:
10301031
10311032``` kotlin
10321033(1 .. 3 ).asFlow().map { requestFlow(it) }
10331034```
10341035
10351036<!-- - CLEAR -->
10361037
1037- Then we end up with a flow of flows (` Flow<Flow<String>> ` ) that needs to be _ flattened_ into a single flow for
1038+ Then we will end up with a flow of flows (` Flow<Flow<String>> ` ) that needs to be _ flattened_ into a single flow for
10381039further processing. Collections and sequences have [ flatten] [ Sequence.flatten ] and [ flatMap] [ Sequence.flatMap ]
10391040operators for this. However, due to the asynchronous nature of flows they call for different _ modes_ of flattening,
1040- as such, there is a family of flattening operators on flows.
1041+ and hence, a family of flattening operators on flows exists .
10411042
10421043### flatMapConcat
10431044
1044- Concatenating mode is implemented by [ flatMapConcat] and [ flattenConcat] operators. They are the most direct
1045- analogues of the corresponding sequence operators. They wait for the inner flow to complete before
1045+ Concatenation of flows of flows is provided by the [ flatMapConcat] and [ flattenConcat] operators. They are the
1046+ most direct analogues of the corresponding sequence operators. They wait for the inner flow to complete before
10461047starting to collect the next one as the following example shows:
10471048
10481049``` kotlin
@@ -1058,7 +1059,7 @@ fun requestFlow(i: Int): Flow<String> = flow {
10581059fun main () = runBlocking<Unit > {
10591060// sampleStart
10601061 val startTime = System .currentTimeMillis() // remember the start time
1061- (1 .. 3 ).asFlow().onEach { delay(100 ) } // a number every 100 ms
1062+ (1 .. 3 ).asFlow().onEach { delay(100 ) } // emit a number every 100 ms
10621063 .flatMapConcat { requestFlow(it) }
10631064 .collect { value -> // collect and print
10641065 println (" $value at ${System .currentTimeMillis() - startTime} ms from start" )
@@ -1087,7 +1088,7 @@ The sequential nature of [flatMapConcat] is clearly seen in the output:
10871088
10881089### flatMapMerge
10891090
1090- Another flattening mode is to concurrently collect all the incoming flows and merge their values into
1091+ Another flattening operation is to concurrently collect all the incoming flows and merge their values into
10911092a single flow so that values are emitted as soon as possible.
10921093It is implemented by [ flatMapMerge] and [ flattenMerge] operators. They both accept an optional
10931094` concurrency ` parameter that limits the number of concurrent flows that are collected at the same time
@@ -1141,9 +1142,9 @@ The concurrent nature of [flatMapMerge] is obvious:
11411142
11421143### flatMapLatest
11431144
1144- In a similar way to the [ collectLatest] operator, that was shown in
1145- [ "Processing the latest value"] ( #processing-the-latest-value ) section , there is the corresponding "Latest"
1146- flattening mode where a collection of the previous flow is cancelled as soon as new flow is emitted.
1145+ In a similar way to the [ collectLatest] operator, that was described in the section
1146+ [ "Processing the latest value"] ( #processing-the-latest-value ) , there is the corresponding "Latest"
1147+ flattening mode where the collection of the previous flow is cancelled as soon as new flow is emitted.
11471148It is implemented by the [ flatMapLatest] operator.
11481149
11491150``` kotlin
@@ -1184,9 +1185,11 @@ The output here in this example is a good demonstration of how [flatMapLatest] w
11841185
11851186<!-- - TEST ARBITRARY_TIME -->
11861187
1187- > Note that [ flatMapLatest] cancels all the code in its block (` { requestFlow(it) } ` in this example) on a new value.
1188+ > Note that [ flatMapLatest] cancels all the code in its block (` { requestFlow(it) } ` in this example when a new value
1189+ > is received.
11881190> It makes no difference in this particular example, because the call to ` requestFlow ` itself is fast, not-suspending,
1189- > and cannot be cancelled. However, it would show up if we were to use suspending functions like ` delay ` in there.
1191+ > and cannot be cancelled. However, a differnce in output would be visible if we were to use suspending functions
1192+ > like ` delay ` in ` requestFlow ` .
11901193>
11911194 {type="note"}
11921195
0 commit comments