#android #kotlin #reactive-programming #kotlin-coroutines #kotlin-flow
Вопрос:
- Сопрограмма 1 возвращает результат<A>;
- Сопрограмма 2 возвращает результат<B>;
- Оба результата должны быть сопоставлены с каким-либо форматом пользовательского интерфейса, например, меню;
- Если сопрограмма 1 завершится неудачно, процесс должен завершиться и вернуть состояние ошибки пользовательского интерфейса;
- если сопрограмма 2 завершится неудачно, она также должна завершить процесс и вернуть состояние ошибки пользовательского интерфейса;
- Сбои сопрограммы обозначаются своего рода пользовательским результатом.Тип сбоя, а не путем создания исключений;
- И сопрограмма 1, и сопрограмма 2 имеют одинаковую обработку ошибок, но имеют разные требования к отображению для их успешного выполнения.
Я подумывал об использовании потока Котлина, но я все еще разбираюсь в реактивном программировании и хотел знать, будет ли это хорошим вариантом использования. Основное осложнение заключается в том, что случаи сбоя не обозначаются исключениями. Кроме того, я просто не знаю, хороший ли это подход. Пожалуйста, будьте добры!
Что-то вроде следующего:
sealed class UiState {
data class menuRetrieved(val menu items: List<MenuItem>) : UiState
object storageError: UiState
object unknownError: UiState
}
val uiState = flowOf(coroutine1.await(), coroutine2.await())
.onEach {
checkIsError(it) // handle potential error cases
}
.transformWhile {
emit(it)
it is Result.Success<*>
}
.map { result: Result.Success<*> ->
result.toMenuItem() // some extension function
}
.collect()
Обратите внимание, что сопрограммы запрашивают локальное хранилище — например, файлы / общие настройки.
Ответ №1:
Похоже, вы ищете оператора zip из flow
Напр.
val flowInt = flowOf(1, 2, 3)
val flowString = flowOf("A", "B", "C")
flowInt.zip(flowString) { intValue, stringValue ->
"$intValue$stringValue"
}.collect {
Log.d(TAG, it)
}
В конечном итоге объедините данные из двух API.
Кредитный блог
Комментарии:
1. Хмм… Не уверен, как это связано с обработкой ошибок.
2. В идеале все ошибки должны быть пойманы таким образом в потоке
.catch { flowCollector -> // Handle error with message }.collect { // Handle success }
, я видел, что несколько ошибок не пойманы оператором catch {}, поэтому мы также помещаем try catch в блок запуска.