I'm launching a coroutine in a view model to do some IO operation such as api call and database queries. I know there are few ways it can be done that's why it's confusing to me which is the right approach.
What's the difference between the two and which is the proper approach?
fun loadProducts() {
viewModelScope.launch {
val productsDeferred = async(Dispatchers.IO) { downloadProducts() }
this.products = productsDeferred.await()
}
}
fun loadProducts2() {
viewModelScope.launch {
this.products = withContext(Dispatchers.IO) { downloadProducts() }
}
}
In this example I'm using a flow to load products from roomdb. I wanted the changes in db to reflect to the UI that's why I used a flow. Do I need to switch context to Dispatchers.IO when calling loadProductsFromDatabaseAsFlow and then switch to Main in the collect block? Again, what's the proper way to do that?
fun loadProducts3() {
viewModelScope.launch {
loadProductsFromDatabaseAsFlow().collect {
this.products = it
}
}
}
CodePudding user response:
What's the difference between the two and which is the proper approach?
async
is mainly used for parallel execution of tasks, that return some result. In your case you launch only one task so I would say that withContext(Dispatchers.IO)
is preferred here.
Do I need to switch context to
Dispatchers.IO
when callingloadProductsFromDatabaseAsFlow
and then switch toMain
in the collect block?
No, you don't need to. You can collect data without switching the context. Flow.collect()
method is suspend
, one of the main purposes of suspend
methods is to be called in the Main
context without blocking the Main
thread. They just suspend the coroutine, but not the current thread.