I have the following method in my viewModel which calls a suspend usecase.
fun clearFirebaseCache() {
viewModelScope.launch {
clearFirebaseCacheUseCase.execute()
}
}
And in my MainActivity it is called like this:
mMainViewModel.changeLanguageConsumableLiveData
.observeAndConsume(this) {
lifecycleScope.launch {
mMainViewModel.clearFirebaseCache()
ProcessPhoenix.triggerRebirth(this@MainActivity)
}
}
As the clearFirebaseCache() has to complete first before calling ProcessPhoenix.triggerRebirth I have added a Deferred so that I can wait for it to finish first.
However, I don't like having this Deferred<Unit> and would prefer a launch as it just clears the cache and returns nothing.
I think it should be in a launch as its not returning anything just a one time call. But as I have to run these in sequence I don't know any other way.
Another thing, having this Deferred makes it more messy as if I want to use this anywhere else I always have to call await, even if I don't have any calls to make in sequence.
This is the final solution
Take in a lamba that will be called after cleared cache
fun clearFirebaseCache() {
viewModelScope.launch {
clearFirebaseCacheUseCase.execute()
}
}
And using it like this, not sure if this is a good pattern or not.
mMainViewModel.changeLanguageConsumableLiveData
.observeAndConsume(this) {
lifecycleScope.launch {
mMainViewModel.clearFirebaseCache(waitUntilComplete = {
ProcessPhoenix.triggerRebirth(this@MainActivity)
})
}
}
Waiting for a suspend function to finish is a default behavior when calling it, we don't need any deferreds,
launch(), etc.:Then:
As simple as that.
Your approach with
Deferredor a callback should work as well, but this is the traditional solution and coroutines were invented specifically to replace such patterns with a better alternative. As we can see in the example above, the code greatly simplifies by using a suspend function and calling it directly.