Coroutines
Context
Coroutines have to be run inside a context.
Suspend function
Suspend functions make sense to start only from coroutine (compilation requirements). And some functions (e.g. delay()) are making sense only inside of suspend functions.
Suspend function can be called from
another suspend function
from coroutine (This is the way actually to start a "first" suspend function)
Testing of suspend function
Builders
Launch
Launch creates a coroutine and submit it to the separate thread, main thread will not wait until the coroutine is finished.
runBlocking
This can be useful to use in tests (to make test a coroutine to be able to invoke suspend function in the test).
runBlocking
is used as a bridge between regular and suspending functions, or between the blocking and non-blocking worlds. It works as an adaptor for starting the top-level main coroutine. It is intended primarily to be used in main()
functions and tests.
async
async
starts a new coroutine and returns a Deferred
object. Deferred
represents a concept known by other names such as Future
or Promise
. It stores a computation, but it defers the moment you get the final result; it promises the result sometime in the future.
The main difference between async
and launch
is that launch
is used to start a computation that isn't expected to return a specific result. launch
returns a Job
that represents the coroutine. It is possible to wait until it completes by calling Job.join()
.
Deferred
is a generic type that extends Job
. An async
call can return a Deferred<Int>
or a Deferred<CustomType>
, depending on what the lambda returns (the last expression inside the lambda is the result).
To get the result of a coroutine, you can call await()
on the Deferred
instance. While waiting for the result, the coroutine that this await()
is called from is suspended:
Structured concurrency
The coroutine scope is responsible for the structure and parent-child relationships between different coroutines. New coroutines usually need to be started inside a scope.
When launch
, async
, or runBlocking
are used to start a new coroutine, they automatically create the corresponding scope. All of these functions take a lambda with a receiver as an argument, and CoroutineScope
is the implicit receiver type:
Control
Join
Similar to joining a thread. The calling thread blocks until coroutine is finished.
Launch returns Job, which has join method. We can also check is coroutine is finished.
Cancel
In order to be cancellable coroutine should be able to check for cancellation.
E.g. delay()
function knows how to cancel.
It is possible to check the status itself (it did not work on my machine, but I took it from the course)
Last updated
Was this helpful?