-
Notifications
You must be signed in to change notification settings - Fork 241
coroutines homework #261
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
coroutines homework #261
Conversation
sergeykamilyevich
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
привет! оставил пару комментариев
|
|
||
| class CatsViewModel(private val catsService: CatsService) : ViewModel() { | ||
| private val _uiModelFlow = MutableStateFlow<Result>(Result.Loading) | ||
| val uiModelFlow: StateFlow<Result> = _uiModelFlow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
лучше в конце добавлять .asStateFlow() чтобы нельзя было скастить к MutableStateFlow
| sealed interface Result { | ||
| data class Success(val uiModel: CatsUiModel) : Result | ||
| data class Error(val message: String?) : Result | ||
| object Loading : Result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
минорно, для удобства лучше сделать data object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Только ради генерации toString()? Ну да, хуже не будет.) Но для этого надо котлин поднять в проекте, так что пожалуй не буду
| private val _uiModelFlow = MutableStateFlow<Result>(Result.Loading) | ||
| val uiModelFlow: StateFlow<Result> = _uiModelFlow | ||
| private val exceptionHandler = CoroutineExceptionHandler { _, e -> | ||
| when (e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
в exceptionHandler лучше не обрабатывать ошибки, а только делать логирование, что и указано в условиях задачи, сюда должны попасть неперехваченные в try-catch ошибки
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тогда стэйт ошибки не дойдет никогда до ui. Либо внутри async ловить ошибки, тогда они не дойдут до exceptionHandler-а, чтобы там залогироваться. Либо давать им уходить в exceptionHandler и если там только логировать, то стэйт не обновиться.
| viewModelScope.coroutineContext.cancelChildren() | ||
| viewModelScope.launch(exceptionHandler) { | ||
| _uiModelFlow.emit(Result.Loading) | ||
| val factJob = async(Dispatchers.IO) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
хорошая практика передавать Dispatchers через конструктор вьюмодели, чтобы его можно было подменять (например в тестах)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не спорю, не было такой задачи
| null | ||
| } | ||
| } catch (e: Throwable) { | ||
| ensureActive() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тут эта проверка не имеет особого смысла, лучше в блоке when сделать проброс CancellationException дальше:
if (e is CancellationException) throw e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"ensureActive()" короче чем "if (e is CancellationException) throw e" и делает примерно тоже самое
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ensureActive кидает новый эксепшн с новым стек трейсом, а throw e пробрасывает дальше исходный
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Так это новый CancellationException, какой там стэктрэйс нужен?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
перехватывать и подменять CancellationException в данном случае совершенно неоправданная практика, ты потеряешь оригинальное сообщение, причину и место выброса
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ок, хотя я не до конца понимаю, где эта инфа может понадобиться
| } else { | ||
| null | ||
| } | ||
| } catch (e: Throwable) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
нет обработки SocketTimeoutException
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А там четко не сказано, что это надо для картинок и что вообще должно происходить, когда ошибка только в одном из запросов. Какое условие такой и результат
| } | ||
|
|
||
| scope.launch { | ||
| val fact = factJob.await() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тут не выполнено требование одновременной отмены запросов, и launch и оба async запущены на одной SupervisorJob и отмена одной загрузки никак не повлияет на другую
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Там нет такого требования там написано: "Отменятся запросы должны одновременно". Там не написано отменять оба запроса в случае ошибки в любом из них. Отменяю я запросы при закрытии экрана вместе с гибелью скоупа. Это происходит одновременно
No description provided.