在 ViewModel 中实现 CoroutineScope
Implementing CoroutineScope in ViewModel
我们为什么以及何时真正需要在 ViewModel
中实施 CoroutineScope
。在 ViewModel 中,当您想将协程绑定到 ViewModel 时,您可以使用 viewModelScope
,因此当 onCleared
被调用时,所有 运行 协程将自动取消。你实现CoroutineScope
的时候可以直接调用launch
,它用的是什么作用域?我猜它使用 override val coroutineContext: CoroutineContext
提供的那个。在 ViewModel 中实现 CoroutineScope
是否意味着您想自己处理协程的取消?
我们可以在 viewmodelscope.launch{} 内启动多个协程而无需 coroutineScope.But 有时我们可能需要来自所有 运行 协程的值来创建新的 result.if 它 return 是一个我们可以使用 async{}.await() 的值,但如果它 return 是我们不能期望更新结果的工作。
因此,如果我们使用 coroutineScope{} 在子协程中启动所有协程,父协程将等待子协程在 return 结果之前完成它的执行。
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()}
这不是很常见。创建 CoroutineScope 的目的是管理多个协程的生命周期。如果由于某种原因你有一些你想在 ViewModel 中启动的协同程序,并且你希望在某个时间取消所有这些协同程序而不是在 ViewModel 被销毁时,那么从 viewModelScope
从中启动那些协程。您可以在适当的时候取消此作用域,以避免协程比您希望的寿命更长和内存泄漏。
如果您的 ViewModel 本身实现了 CoroutineScope 并且您直接调用 launch
,它会将自身用作启动协程的范围。但是在适当的时候取消它仍然取决于你。否则,ViewModel 可能处于销毁状态,但在其范围内仍有一些协程 运行 并挂在内存中并阻止 ViewModel 被释放到 GC。
我们为什么以及何时真正需要在 ViewModel
中实施 CoroutineScope
。在 ViewModel 中,当您想将协程绑定到 ViewModel 时,您可以使用 viewModelScope
,因此当 onCleared
被调用时,所有 运行 协程将自动取消。你实现CoroutineScope
的时候可以直接调用launch
,它用的是什么作用域?我猜它使用 override val coroutineContext: CoroutineContext
提供的那个。在 ViewModel 中实现 CoroutineScope
是否意味着您想自己处理协程的取消?
我们可以在 viewmodelscope.launch{} 内启动多个协程而无需 coroutineScope.But 有时我们可能需要来自所有 运行 协程的值来创建新的 result.if 它 return 是一个我们可以使用 async{}.await() 的值,但如果它 return 是我们不能期望更新结果的工作。
因此,如果我们使用 coroutineScope{} 在子协程中启动所有协程,父协程将等待子协程在 return 结果之前完成它的执行。
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()}
这不是很常见。创建 CoroutineScope 的目的是管理多个协程的生命周期。如果由于某种原因你有一些你想在 ViewModel 中启动的协同程序,并且你希望在某个时间取消所有这些协同程序而不是在 ViewModel 被销毁时,那么从 viewModelScope
从中启动那些协程。您可以在适当的时候取消此作用域,以避免协程比您希望的寿命更长和内存泄漏。
如果您的 ViewModel 本身实现了 CoroutineScope 并且您直接调用 launch
,它会将自身用作启动协程的范围。但是在适当的时候取消它仍然取决于你。否则,ViewModel 可能处于销毁状态,但在其范围内仍有一些协程 运行 并挂在内存中并阻止 ViewModel 被释放到 GC。