Search⌘ K
AI Features

Coroutine Scope Functions

Explore Kotlin coroutine scope functions to manage concurrent operations in suspending functions. Understand pitfalls of common approaches, benefits of coroutineScope, and how it maintains parent-child relationships, cancellation, and proper coroutine context. This lesson helps you write safer, testable concurrent code in Kotlin.

Imagine that we need to concurrently get data from two (or more) endpoints in a suspending function. Before we explore how to do this correctly, let’s see some suboptimal approaches.

Approaches used before coroutine scope functions

The first approach is calling suspending functions from a suspending function. The problem with this solution is that it’s not concurrent (for example, if getting data from each endpoint takes one second, a function will take two seconds instead of one).

Kotlin 1.5
// Data loaded sequentially, not simultaneously
suspend fun getUserProfile(): UserProfileData {
val user = getUserData() // (1 sec)
val notifications = getNotifications() // (1 sec)
return UserProfileData(
user = user,
notifications = notifications,
)
}

The easiest way to make two suspending calls concurrently is by wrapping them with async. However, async requires a scope, and using GlobalScope is not a good idea.

Kotlin 1.5
//DOING THIS IS NOT RECOMMENDED AT ALL
suspend fun getUserProfile(): UserProfileData {
val user = GlobalScope.async { getUserData() }
val notifications = GlobalScope.async {
getNotifications()
}
return UserProfileData(
user = user.await(), // (1 sec)
notifications = notifications.await(),
)
}

The GlobalScope ...