Skip to content

Commit a6da28e

Browse files
committed
Merge branch 'master' into develop
# Conflicts: # docs/coroutine-context-and-dispatchers.md
2 parents d533848 + 8ab2130 commit a6da28e

File tree

3 files changed

+97
-95
lines changed

3 files changed

+97
-95
lines changed

docs/composing-suspending-functions.md

+27-26
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ suspend fun doSomethingUsefulTwo(): Int {
5656
</div>
5757

5858

59-
What do we do if need to invoke them _sequentially_ -- first `doSomethingUsefulOne` _and then_
60-
`doSomethingUsefulTwo` and compute the sum of their results?
61-
In practice we do this if we use the results of the first function to make a decision on whether we need
59+
What do we do if we need them to be invoked _sequentially_ &mdash; first `doSomethingUsefulOne` _and then_
60+
`doSomethingUsefulTwo`, and compute the sum of their results?
61+
In practice we do this if we use the result of the first function to make a decision on whether we need
6262
to invoke the second one or to decide on how to invoke it.
6363

6464
We use a normal sequential invocation, because the code in the coroutine, just like in the regular
@@ -110,12 +110,12 @@ Completed in 2017 ms
110110

111111
### Concurrent using async
112112

113-
What if there are no dependencies between invocation of `doSomethingUsefulOne` and `doSomethingUsefulTwo` and
113+
What if there are no dependencies between invocations of `doSomethingUsefulOne` and `doSomethingUsefulTwo` and
114114
we want to get the answer faster, by doing both _concurrently_? This is where [async] comes to help.
115115

116116
Conceptually, [async] is just like [launch]. It starts a separate coroutine which is a light-weight thread
117117
that works concurrently with all the other coroutines. The difference is that `launch` returns a [Job] and
118-
does not carry any resulting value, while `async` returns a [Deferred] -- a light-weight non-blocking future
118+
does not carry any resulting value, while `async` returns a [Deferred] &mdash; a light-weight non-blocking future
119119
that represents a promise to provide a result later. You can use `.await()` on a deferred value to get its eventual result,
120120
but `Deferred` is also a `Job`, so you can cancel it if needed.
121121

@@ -161,14 +161,14 @@ Completed in 1017 ms
161161

162162
<!--- TEST ARBITRARY_TIME -->
163163

164-
This is twice as fast, because we have concurrent execution of two coroutines.
164+
This is twice as fast, because the two coroutines execute concurrently.
165165
Note that concurrency with coroutines is always explicit.
166166

167167
### Lazily started async
168168

169-
There is a laziness option to [async] using an optional `start` parameter with a value of [CoroutineStart.LAZY].
170-
It starts coroutine only when its result is needed by some
171-
[await][Deferred.await] or if a [start][Job.start] function
169+
Optionally, [async] can be made lazy by setting its `start` parameter to [CoroutineStart.LAZY].
170+
In this mode it only starts the coroutine when its result is required by
171+
[await][Deferred.await], or if its `Job`'s [start][Job.start] function
172172
is invoked. Run the following example:
173173

174174
<div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -219,18 +219,18 @@ So, here the two coroutines are defined but not executed as in the previous exam
219219
the programmer on when exactly to start the execution by calling [start][Job.start]. We first
220220
start `one`, then start `two`, and then await for the individual coroutines to finish.
221221

222-
Note that if we have called [await][Deferred.await] in `println` and omitted [start][Job.start] on individual
223-
coroutines, then we would have got the sequential behaviour as [await][Deferred.await] starts the coroutine
224-
execution and waits for the execution to finish, which is not the intended use-case for laziness.
222+
Note that if we just call [await][Deferred.await] in `println` without first calling [start][Job.start] on individual
223+
coroutines, this will lead to sequential behavior, since [await][Deferred.await] starts the coroutine
224+
execution and waits for its finish, which is not the intended use-case for laziness.
225225
The use-case for `async(start = CoroutineStart.LAZY)` is a replacement for the
226226
standard `lazy` function in cases when computation of the value involves suspending functions.
227227

228228
### Async-style functions
229229

230230
We can define async-style functions that invoke `doSomethingUsefulOne` and `doSomethingUsefulTwo`
231-
_asynchronously_ using [async] coroutine builder with an explicit [GlobalScope] reference.
232-
We name such functions with
233-
"Async" suffix to highlight the fact that they only start asynchronous computation and one needs
231+
_asynchronously_ using the [async] coroutine builder with an explicit [GlobalScope] reference.
232+
We name such functions with the
233+
"...Async" suffix to highlight the fact that they only start asynchronous computation and one needs
234234
to use the resulting deferred value to get the result.
235235

236236
<div class="sample" markdown="1" theme="idea" data-highlight-only>
@@ -310,21 +310,21 @@ Completed in 1085 ms
310310

311311
> This programming style with async functions is provided here only for illustration, because it is a popular style
312312
in other programming languages. Using this style with Kotlin coroutines is **strongly discouraged** for the
313-
reasons that are explained below.
313+
reasons explained below.
314314

315-
Consider what happens if between `val one = somethingUsefulOneAsync()` line and `one.await()` expression there is some logic
315+
Consider what happens if between the `val one = somethingUsefulOneAsync()` line and `one.await()` expression there is some logic
316316
error in the code and the program throws an exception and the operation that was being performed by the program aborts.
317317
Normally, a global error-handler could catch this exception, log and report the error for developers, but the program
318-
could otherwise continue doing other operations. But here we have `somethingUsefulOneAsync` still running in background,
319-
despite the fact, that operation that had initiated it aborts. This problem does not happen with structured
318+
could otherwise continue doing other operations. But here we have `somethingUsefulOneAsync` still running in the background,
319+
even though the operation that initiated it was aborted. This problem does not happen with structured
320320
concurrency, as shown in the section below.
321321

322322
### Structured concurrency with async
323323

324-
Let us take [Concurrent using async](#concurrent-using-async) example and extract a function that
324+
Let us take the [Concurrent using async](#concurrent-using-async) example and extract a function that
325325
concurrently performs `doSomethingUsefulOne` and `doSomethingUsefulTwo` and returns the sum of their results.
326-
Because [async] coroutines builder is defined as extension on [CoroutineScope] we need to have it in the
327-
scope and that is what [coroutineScope] function provides:
326+
Because the [async] coroutine builder is defined as an extension on [CoroutineScope], we need to have it in the
327+
scope and that is what the [coroutineScope] function provides:
328328

329329
<div class="sample" markdown="1" theme="idea" data-highlight-only>
330330

@@ -338,8 +338,8 @@ suspend fun concurrentSum(): Int = coroutineScope {
338338

339339
</div>
340340

341-
This way, if something goes wrong inside the code of `concurrentSum` function and it throws an exception,
342-
all the coroutines that were launched in its scope are cancelled.
341+
This way, if something goes wrong inside the code of the `concurrentSum` function and it throws an exception,
342+
all the coroutines that were launched in its scope will be cancelled.
343343

344344
<!--- CLEAR -->
345345

@@ -379,7 +379,7 @@ suspend fun doSomethingUsefulTwo(): Int {
379379

380380
> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-compose-05.kt).
381381
382-
We still have concurrent execution of both operations as evident from the output of the above main function:
382+
We still have concurrent execution of both operations, as evident from the output of the above `main` function:
383383

384384
```text
385385
The answer is 42
@@ -426,7 +426,8 @@ suspend fun failedConcurrentSum(): Int = coroutineScope {
426426

427427
> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-compose-06.kt).
428428
429-
Note, how both first `async` and awaiting parent are cancelled on the one child failure:
429+
Note how both the first `async` and the awaiting parent are cancelled on failure of one of the children
430+
(namely, `two`):
430431
```text
431432
Second child throws an exception
432433
First child was cancelled

0 commit comments

Comments
 (0)