Kotlin Coroutines Cheat Sheet
Tags: kotlin, coroutines, android
Published: 2019-12-12 15:54:40

Recently I was refreshing myself on kotlin coroutines, as I had worked with them before but never fulled grasped all the ins and outs of coroutines, and I decided to make some notes while I was reading through the docs (https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html). 
I figured they would be helpful to other kotlin developers. Note that these are quick notes I jotted down and isn't a fully grammatical tutorial-esque article.

##Summary
Coroutines are light-weight threads

__CoroutineScope__ - Used to build coroutines, contains CoroutineContext
	Scope Types:
* __GlobalScope__ - Lifetime of the new coroutine is limited only by the lifetime of the whole application
* __CoroutineScope__ - Is destroyed after all launched children are completed
* __MainScope__ - Scope for UI applications and uses Dispatchers.Main

__CoroutineContext__ - A collection of various elements. Contains Job and CoroutineDispatcher
__CoroutineDispatcher__ - Determines the thread(s) to use
	Dispatcher types:
* __Unconfined__ - I’m working in thread main (appropriate for coroutines which neither consume CPU time nor update any shared data (like UI) confined to a specific thread)
* __Default__ -  I'm working in thread DefaultDispatcher-worker-1
* __newSingleThreadContext__ - I’m working in thread MyOwnThread
* __main runBlocking__ - I’m working in thread main
* __newSingleThreadContext()__ - Creates new thread, can be used to switch between using withContext


####Launch
* Launch is a coroutine builder that returns a Job
* Launch inherits the context from the scope it’s launched from
* Customizing Launch:
    * Can pass variables between threads using `asContextElement`
    * Can name Coroutines using `CoroutineName`

####Async
* Async is like launch, but returns a Deferred (i.e. future)
* Async `CoroutineStart.LAZY` only starts when await is called

####Cancellation
* Jobs can be cancelled or call join, which works like pthread_join
* Coroutine cancellation is cooperative, meaning if the coroutine isn’t checking if it’s cancelled then it won’t be cancelled
* `SupervisorJob` is a job where cancellation is only propagated downwards
* `withTimeout` creates a timeout for the coroutines (throws `TimeoutCancellationException`)
* When cancelled:
    * Job throws an exception which can be handled with finally or catch (`CancellationException`)
    * All child coroutines are cancelled as well

####Suspend
* Suspend can be used inside coroutines, but can also use other suspending functions
* If a coroutine builder is inside suspend function a CoroutineScope needs to be added as well

####Blocking
* `runBlocking` runs a new coroutine and blocks the current thread, interruptible until it’s completion
* Delay is non blocking

####Flow
* Flow is an asynchronous stream of values . Uses `Emit` and `Collect` to send and collect data
* Flow runs in the context that is provided the collector
* The code inside a flow isn’t run until the flow is collected
* Flows can be cancelled with `withTimeoutOrNull`
* Useful functions:
    * **transform** - customize data, such as emitting a header first
    * **take** - only take a certain amount of the flow
    * **flowOn** - change the context of preceding code
    * **zip** - combine multiple flows
    * **catch** - catch any exceptions of preceding code
    * **onCompletion** - perform any final tasks after the flow is done

####Channel
* Similar to a blocking queue, a way to transfer values between coroutines
* Uses `send` and `receive` for normal values, `produce` and `consume` for streams
* Channels can be closed to indicate no more elements are coming

####Actor
* Actor is an entity that can receive a class of messages using sealed classes. Meaning a consumer that takes in sealed classes

Let me know if I got anything wrong, or if I missed anything. Hope this helps!