frankelot
08/29/2021, 9:11 PMCoroutineScope
interface. I get that coroutines builders like launch
are extension functions on that class, but why can’t they just be extension function on CoroutineContext
instead?Jan Groen
08/29/2021, 9:48 PMcoroutineContext
value. Let's consider a theoretical example of what if launch
was an extension function on CoroutineContext
. Then we could write code like this:
suspend fun foo() {
// Do some work
coroutineContext.launch {
delay(1000)
bar()
}
// Do some more work
}
Calling the foo
method could return, while the code inside the launch method is still active. While this code would work theoretically, it is not ideomatic, because a suspending function is designed to only return when all its work is completed and is not supposed to launch anything else that might complete at a later time. (Paraphrasing the closing statement of the article you mentioned here)
To correct the code above we could do something like this:
suspend fun foo() = coroutineScope {
// Do some work
launch {
delay(1000)
bar()
}
// Do some more work
}
This would lead to the behavior we expect from a suspending function in that it only returns after all of it's calculations are complete.frankelot
08/29/2021, 9:49 PMstreetsofboston
08/30/2021, 12:17 AMcoroutineContext[Job]
could serve as the CoroutineScope...
In other words, it keeps the two concerns apart:
1. cancellation, awaiting child completion, exception handling;
2. context such as current Dispatcher, custom Elements (like ThreadLocal, but for suspend), name (eg for debugging), etcfrankelot
08/30/2021, 11:20 AM(eg cancellation, awaiting child job completions,Right, an example of cancellation would be what
ViewModelScope
does in Android and an example of child job completions
would be coroutineScope { ... }
right