-
Notifications
You must be signed in to change notification settings - Fork 22
Using join in coroutines
Devrath edited this page Jan 15, 2024
·
2 revisions
The join function in coroutines is used to wait for the completion of a coroutine. When you launch a coroutine, it runs asynchronously, and the code that follows the launch statement continues to execute immediately without waiting for the coroutine to finish. However, there might be cases where you need to wait for the coroutine to complete before proceeding with the next steps.
Observe that still parent coroutine has not finished execution so .join()
helps us to achieve this behaviour.
Parent-1 ----- tick ----->0
Parent-1 ----- tick ----->1
Parent-1 ----- tick ----->2
<--------------- User invokes cancel------------------->
Exception caught inside GrandParent scope
Exception caught inside Parent-1 coroutine
GrandParent invokeOnCompletion triggered
class UsingJoinDemoVm @Inject constructor( ) : ViewModel() {
private val scopeJob = Job()
private val ourScope = CoroutineScope(scopeJob + Dispatchers.Default)
fun demo() {
try {
ourScope.launch(CoroutineName("GrandParent")) {
try {
parent1Block().join()
parent2Block().join()
println("Both parent code blocks are completed")
}catch (ex:Exception){
println("Exception caught inside GrandParent scope")
}
}.invokeOnCompletion {
println("GrandParent invokeOnCompletion triggered")
}
}catch (ex:Exception){
println("Exception caught outside GrandParent scope")
}
}
private suspend fun parent1Block() = ourScope.launch(CoroutineName("Parent-1")) {
try {
repeat(10){
println("Parent-1 ----- tick ----->$it")
delay(1000)
}
}catch (ex:Exception){
println("Exception caught inside Parent-1 coroutine")
}
}
private suspend fun parent2Block() = ourScope.launch(CoroutineName("Parent-2")) {
try {
parent2Child1Block().join()
println("Parent-2-Child-1 block is completed")
repeat(10){
println("Parent-2-Child-1 ----- tick ----->$it")
delay(1000)
}
}catch (ex:Exception){
println("Exception caught inside Parent-2 coroutine")
}
}
private suspend fun parent2Child1Block() = ourScope.launch(CoroutineName("Parent-2-Child-1")) {
try {
repeat(10){
println("Parent-2-Child-1 ----- tick ----->$it")
delay(1000)
}
}catch (ex:Exception){
println("Exception caught inside Parent-2-Child-1 coroutine")
}
}
fun rootCancel() {
scopeJob?.cancel()
}
}