One of the most important benefits of the coroutines approach is a guarantee that functions are invoked in the same order in which they are written. The order of the operations is a very important nuance when we execute concurrent code in a multithreaded environment.
Let's imagine that we have to load a user's details, using the following function:
suspend fun loadUserDetails(): User {
delay(3000)
return User(0, "avatar")
}
The loadUserDetails function invokes the delay function from the coroutines-core library and returns an instance of the User class. The delay function suspends the invocation of the current coroutine. When a user is ready, we have to pass a value of the avatar property to the loadImage function:
suspend fun loadImage(avatar: String): Image {
delay(3000)
return Image()
}
The loadImage function also invokes...