Kt. Academy Logo

Kotlin Coroutines

Our special learning place

Part 1: Understanding Kotlin Coroutines
Why Kotlin Coroutines?
Sequence builder
Exercise: Factorial sequence
Exercise: Prime numbers sequence
How does suspension work?
Exercise: Callback function wrappers
Exercise: Continuation storage
Coroutines under the hood
Exercise: What is stored by a continuation?
Coroutines: built-in support vs library
Part 2: Kotlin Coroutines library
Starting coroutines
Exercise: Showing user details
Exercise: Finding the best student
Exercise: CommentService
Exercise: mapAsync
The bigger picture
Coroutine context
Exercise: Understanding context propagation
Exercise: CounterContext
Exercise: Using dispatchers
Exercise: DiscNewsRepository
Exercise: Experiments with dispatchers
Job and coroutine lifecycle
Exercise: Correct mistakes with cancellation
Exception handling
Constructing a coroutine scope
Exercise: NotificationSender
Exercise: BasePresenter
The problem with shared state
Exercise: UserDownloader
Exercise: CompanyDetailsRepository
Exercise: CancellingRefresher
Exercise: Suspended lazy
Exercise: mapAsync with concurrency limit
Testing Kotlin Coroutines
Exercise: Testing a suspending function
Exercise: Testing mapAsync
Exercise: Testing the NotificationSender class
Exercise: Testing a View Model
Part 3: Channel and Flow
Exercise: UserRefresher
Exercise: Cafeteria simulation
Exercise: raceOf
Hot and cold data sources
Flow introduction
Understanding Flow
Flow building
Exercise: Flow utils
Exercise: All users flow
Exercise: distinct
Flow lifecycle functions
Exercise: NewsViewModel
Flow processing
merge, zip and combine
fold and scan
flatMapConcat, flatMapMerge and flatMapLatest
Distinct until changed
Terminal operations
Exercise: ProductService
Exercise: Flow Kata
Exercise: MessageService
SharedFlow and StateFlow
Exercise: LocationService
Exercise: PriceService
Exercise: NewsViewModel using shareIn
Testing flow
Exercise: Flow testing
Part 4: Kotlin Coroutines in practice
Common use cases
Data/Adapters Layer
Domain Layer
Presentation/API/UI layer
Kotlin Coroutines library was designed to suit our typical backend and Android use cases. That means, that even though every problem can be solved in many ways, for most situations, there are well established patterns that should be preferred. Some of them are expressed by Kotlin Coroutines creators themselves, while others are established by discussions in our community. I collected those use cases, and I would like to present my vision of how Kotlin Coroutines should be used in typical use cases, in typical applications.
Using coroutines from other languages
Launching coroutines vs. suspending functions
Best practices