Coroutines Concepts
Suspend Function Shape
A suspend function can be called from another suspend context and still return an ordinary value.
suspend function
A suspend function marks work that can cooperate with a coroutine context, even when this tiny example completes immediately.
Suspend Function Shape
SuspendFunctionShape.kt
Replay: real traced execution (multi-file project)
import kotlin.coroutines.Continuation
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.startCoroutine
suspend fun loadLabel(id: Int): String {
val normalized = id.coerceAtLeast(0)
return "item-$normalized"
}
fun main() {
val id = 2
var output = "pending"
val job: suspend () -> String = {
loadLabel(id)
}
job.startCoroutine(object : Continuation<String> {
override val context = EmptyCoroutineContext
override fun resumeWith(result: Result<String>) {
output = result.getOrThrow()
}
})
println("result=$output")
}
import kotlin.coroutines.Continuation
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.startCoroutine
suspend fun loadLabel(id: Int): String {
val normalized = id.coerceAtLeast(0)
return "item-$normalized"
}
fun main() {
val id = 0
var output = "pending"
val job: suspend () -> String = {
loadLabel(id)
}
job.startCoroutine(object : Continuation<String> {
override val context = EmptyCoroutineContext
override fun resumeWith(result: Result<String>) {
output = result.getOrThrow()
}
})
println("result=$output")
}
import kotlin.coroutines.Continuation
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.startCoroutine
suspend fun loadLabel(id: Int): String {
val normalized = id.coerceAtLeast(0)
return "item-$normalized"
}
fun main() {
val id = 5
var output = "pending"
val job: suspend () -> String = {
loadLabel(id)
}
job.startCoroutine(object : Continuation<String> {
override val context = EmptyCoroutineContext
override fun resumeWith(result: Result<String>) {
output = result.getOrThrow()
}
})
println("result=$output")
}
id ← 2, output ← pending, job ← () -> kotlin.String
10fun main() {11 val id→ 2 = 2 //@id=0, 512 var output→ pending = "pending"1314 val job→ () -> kotlin.String: suspend () -> String = {15 loadLabel(id)16 }1718 job() -> kotlin.String.startCoroutine(object : Continuation<String> {19 override val context = EmptyCoroutineContext2021 override fun resumeWith(result: Result<String>) {22 output = result.getOrThrow()23 }24 })normalized ← 2
5suspend fun loadLabel(id2: Int): String {6 val normalized→ 2 = id2.coerceAtLeast(0)7 return "item-$normalized2"8}override fun resumeWith(result: Result<String>)
18job() -> kotlin.String.startCoroutine(object : Continuation<String> {19 override val context = EmptyCoroutineContext2021 override fun resumeWith(resultSuccess(item-2): Result<String>) {22 output = resultSuccess(item-2).getOrThrow()23 }24})println("result=$output")
26 println("result=$outputitem-2")27}outputresult=item-2
id ← 0, output ← pending, job ← () -> kotlin.String
10fun main() {11 val id→ 0 = 012 var output→ pending = "pending"1314 val job→ () -> kotlin.String: suspend () -> String = {15 loadLabel(id)16 }1718 job() -> kotlin.String.startCoroutine(object : Continuation<String> {19 override val context = EmptyCoroutineContext2021 override fun resumeWith(result: Result<String>) {22 output = result.getOrThrow()23 }24 })normalized ← 0
5suspend fun loadLabel(id0: Int): String {6 val normalized→ 0 = id0.coerceAtLeast(0)7 return "item-$normalized0"8}override fun resumeWith(result: Result<String>)
18job() -> kotlin.String.startCoroutine(object : Continuation<String> {19 override val context = EmptyCoroutineContext2021 override fun resumeWith(resultSuccess(item-0): Result<String>) {22 output = resultSuccess(item-0).getOrThrow()23 }24})println("result=$output")
26 println("result=$outputitem-0")27}outputresult=item-0
id ← 5, output ← pending, job ← () -> kotlin.String
10fun main() {11 val id→ 5 = 512 var output→ pending = "pending"1314 val job→ () -> kotlin.String: suspend () -> String = {15 loadLabel(id)16 }1718 job() -> kotlin.String.startCoroutine(object : Continuation<String> {19 override val context = EmptyCoroutineContext2021 override fun resumeWith(result: Result<String>) {22 output = result.getOrThrow()23 }24 })normalized ← 5
5suspend fun loadLabel(id5: Int): String {6 val normalized→ 5 = id5.coerceAtLeast(0)7 return "item-$normalized5"8}override fun resumeWith(result: Result<String>)
18job() -> kotlin.String.startCoroutine(object : Continuation<String> {19 override val context = EmptyCoroutineContext2021 override fun resumeWith(resultSuccess(item-5): Result<String>) {22 output = resultSuccess(item-5).getOrThrow()23 }24})println("result=$output")
26 println("result=$outputitem-5")27}outputresult=item-5