Несмотря на то, что ваш подход правильный, вы всегда можете внести некоторые улучшения, чтобы упростить его или сделать его более идиоматичным c (особенно если вас не устраивает собственный код).
Это лишь некоторые предложения которые вы можете принять во внимание:
Вы можете использовать Kotlin Scope Functions, или, более конкретно, функцию let
следующим образом:
private suspend fun getStories() = withContext(Dispatchers.IO) {
storyRepository.fetchStories()?.let { snapshots ->
val networkStories = snapshots.toObjects(NetworkStory::class.java)
NetworkStoryContainer(networkStories).asDomainModel()
} ?: throw CancellationException("Task is null; local DB not refreshed")
}
This way you ' буду возвращать ваши данные или бросать CancellationException
if null
.
Когда вы работаете с сопрограммами внутри ViewModel, у вас есть CoroutineScope, готовый к использованию, если вы добавите эту зависимость в свой файл gradle:
androidx.lifecycle:lifecycle-viewmodel-ktx:{version}
Таким образом, вы можете использовать viewModelScope
для создания ваших сопрограмм, которые будут работать в основном потоке:
init {
viewModelScope.launch {
_stories.value = getStories()
}
viewModelScope.launch {
getMetadata()
}
}
Вы можете забыть об отмене его Job
во время onCleared
поскольку viewModelScope
учитывает жизненный цикл.
Теперь все, что вам осталось сделать, это обработать исключение с помощью блока try-catch
или с помощью функции invokeOnCompletion
, примененной к Job
, возвращаемому launch
строитель.