Skip to content

Using join in coroutines

Devrath edited this page Jan 15, 2024 · 2 revisions

rocket-flying-cloud-go-moon-galaxy-background-business-startup-concept-3d-model-illustration_307211-440

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.

UseCase-1:Consider the relationship as described

d

Observation

Observe that still parent coroutine has not finished execution so .join() helps us to achieve this behaviour.

Output

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

code

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()
    }

}
Clone this wiki locally