我需要有一个状态在一个视图模型,得到更新的收集从流。我的State类:
data class DevicesUIState(
val currentGroup: GroupEntity? = null,
val currentGroupSubGroups: List<GroupEntity> = listOf(),
val currentGroupSubDevices: List<DeviceEntity> = listOf(),
val allDevices: List<DeviceEntity> = listOf(),
)
应从流设置每个属性。流设置currentGroup & allDevices属性不应等待彼此发出结果。流设置currentGroupSubGroups & currentGroupSubDevices取决于所设置的currentGroup。
每个流从房间DB收集
到目前为止,设置状态属性的代码如下所示
val groupId: Int?
val uiState: StateFlow<DevicesUIState> = groupsRepository.groupFlow(groupId)
.mapLatest {
Timber.e("Mapping currentGroup")
DevicesUIState(currentGroup = it)
}.flatMapLatest { uiState ->
Timber.e("Mapping currentGroupSubGroups")
groupsRepository.subGroupsFlow(uiState.currentGroup?.id).map {
uiState.copy(currentGroupSubGroups = it)
}
}.flatMapLatest { uiState ->
Timber.e("Mapping currentGroupSubDevices")
liteDeviceRepository.subDevicesFlow(uiState.currentGroup?.id).map {
uiState.copy(currentGroupSubDevices = it)
}
}.flatMapLatest { uiState ->
Timber.e("Mapping allDevices")
liteDeviceRepository.allDevicesFlow().map {
uiState.copy(allDevices = it)
}
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000L),
initialValue = DevicesUIState()
)
它的工作。但看看日志消息的流量收集更多的冒犯,我的预期。所以我有一种感觉,我的代码是不是正确的方式做的事情。
日志
I --> GET https://example.com/api/groups
E Mapping currentGroup
E Mapping currentGroupSubGroups
E Mapping currentGroupSubDevices
E Mapping allDevices
I <-- 200 https://example.com/api/groups (393ms, unknown-length body)
E Mapping currentGroup
E Mapping currentGroupSubGroups
E Mapping currentGroupSubDevices
E Mapping allDevices
I --> GET https://example.com/api/devices
I <-- 200 https://example.com/api/devices (85ms, unknown-length body)
E Mapping allDevices
I --> GET https://example.com/api/extraDevicesData
I <-- 200 https://example.com/api/extraDevicesData (258ms, unknown-length body)
E Mapping allDevices
1条答案
按热度按时间n9vozmp41#
为了构建这种结构,使彼此不依赖的流可以并行运行,我将对其进行如下更改。
组和依赖于组的两个组可以使用内部
combine
的flatMapLatest
来创建。这允许子组或子设备更改,而不会触发其他流的重新启动。然后,该结果和
allDevices
流也可以被组合。同样,这允许group和allDevices不触发彼此重启。抱歉有语法错误。我不是在测试这个。
如果两个子流经常同时发出新值,您也可以考虑在合并它们之前对它们进行去抖动。