Home > OS >  Implementing CoroutineScope in ViewModel
Implementing CoroutineScope in ViewModel

Time:02-18

Why and when do we actually need to implement CoroutineScope in a ViewModel. Inside ViewModel you can use viewModelScope when you want to tied your Coroutine to the ViewModel thus when onCleared gets called all running coroutines will be cancelled automatically. When you implement CoroutineScope you can directly call launch, what scope does it use? I am guessing it uses the one provided at override val coroutineContext: CoroutineContext. Does implementing CoroutineScope in a ViewModel means you want to handle the cancellation of coroutine by yourself?

CodePudding user response:

We can launch multiple coroutine within viewmodelscope.launch{} without coroutineScope.But Sometimes we may need values from all running coroutine to create new result.if it returns a value we can use async{}.await() but if it returns a job we can't expect updated result .

So if we launch our all coroutines within our child coroutine using coroutineScope{} ,parent coroutine will wait for child coroutine to finish it's executions before return the result.

viemodelScope.launch{val count= getCountValue()  }//parent coroutine

 suspend fun getCountValue(): Int {
        var count = 0
        lateinit var asyncDeferredResult: Deferred<Int>
 //child coroutine
        coroutineScope { 
            //returns job
            launch(Dispatchers.IO) {
                delay(1000)
                count = 10
            }
            //launching another coroutine using async coroutine builder within child coroutine
            asyncDeferredResult = CoroutineScope(Dispatchers.IO).async {
                delay(3000)
                return@async 50 
            }

        }  //child coroutine scope end


        //here the parent coroutine  guaranties ,the completion of all task within child coroutine scope  before return the value .
        //  we will get expected result (10 50=60) 
        //if you launch more than one coroutine without child coroutinescope,sometimes you will get 0 50=50 at the end

        return count   asyncDeferredResult.await()}

CodePudding user response:

It is not very commonly necessary. The purpose of creating a CoroutineScope is to manage the lifecycle of multiple coroutines. If for some reason you have some coroutines you want to launch in a ViewModel, and you want to possibly cancel all of them at some time other than when the ViewModel is destroyed, then it would be handy to have a separate CoroutineScope from viewModelScope to launch those coroutines from. It would be up to you to cancel this scope at the appropriate time to avoid coroutines living longer than you want them to and leaking memory.

If your ViewModel itself implements CoroutineScope and you directly call launch, it is using itself as the scope that launches the coroutine. But it's still up to you to cancel it at the appropriate time. Otherwise, the ViewModel could be in destroyed state, but still have some coroutines running in its scope and hanging onto memory and preventing the ViewModel from being freed to the GC.

  • Related