Skip to content

Commit 4f686c8

Browse files
authored
Grammar fixes to flow.md (#3382)
1 parent d88a8c2 commit 4f686c8

File tree

2 files changed

+37
-34
lines changed

2 files changed

+37
-34
lines changed

docs/topics/flow.md

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ This code prints the numbers after waiting for a second.
102102
### Flows
103103

104104
Using 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
108108
import kotlinx.coroutines.*
@@ -151,11 +151,11 @@ I'm not blocked 3
151151

152152
Notice 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

217217
This 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
224224
cancelled when the flow is suspended in a cancellable suspending function (like [delay]).
225225
The following example shows how the flow gets cancelled on a timeout when running in a [withTimeoutOrNull] block
226226
and 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
280280
import 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.
305306
Intermediate operators are applied to an upstream flow and return a downstream flow.
306307
These operators are cold, just like flows are. A call to such an operator is not
307308
a suspending function itself. It works quickly, returning the definition of a new transformed flow.
308309

309310
The 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
311312
code inside these operators can call suspending functions.
312313

313314
For 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
315316
operation 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
343344
response 1
@@ -593,7 +594,7 @@ Since `simple().collect` is called from the main thread, the body of `simple`'s
593594
This is the perfect default for fast-running or asynchronous code that does not care about the execution context and
594595
does not block the caller.
595596

596-
### Wrong emission withContext
597+
### A common pitfall when using withContext
597598

598599
However, the long-running CPU-consuming code might need to be executed in the context of [Dispatchers.Default] and UI-updating
599600
code 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
10171018
function 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
10381039
further processing. Collections and sequences have [flatten][Sequence.flatten] and [flatMap][Sequence.flatMap]
10391040
operators 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
10461047
starting to collect the next one as the following example shows:
10471048

10481049
```kotlin
@@ -1058,7 +1059,7 @@ fun requestFlow(i: Int): Flow<String> = flow {
10581059
fun 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
10911092
a single flow so that values are emitted as soon as possible.
10921093
It 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.
11471148
It 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

kotlinx-coroutines-core/jvm/test/guide/example-flow-23.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fun requestFlow(i: Int): Flow<String> = flow {
1616

1717
fun main() = runBlocking<Unit> {
1818
val startTime = currentTimeMillis() // remember the start time
19-
(1..3).asFlow().onEach { delay(100) } // a number every 100 ms
19+
(1..3).asFlow().onEach { delay(100) } // emit a number every 100 ms
2020
.flatMapConcat { requestFlow(it) }
2121
.collect { value -> // collect and print
2222
println("$value at ${currentTimeMillis() - startTime} ms from start")

0 commit comments

Comments
 (0)