我使用的是MutableStateFlow
,我的流类型是密封类,有不同的状态(Loading,Success,Error等)。我的流的初始值为空:
private val _updateDepartmentsState = MutableStateFlow<DepartmentFetchState>(DepartmentFetchState.Empty)
字符串
在我的仓库中,我发出不同的状态。例如:
suspend fun updateDepartments() {
_updateDepartmentsState.emit(DepartmentFetchState.Loading)
try {
remoteDataSource.updateDepartments()
// here some code
_updateDepartmentsState.emit(DepartmentFetchState.Success(data))
} catch(e: NetworkException) {
_updateDepartmentsState.emit(DepartmentFetchState.Error)
}
}
型
在我的仓库中,我也有只读流:
val updateDepartmentsState = _updateDepartmentsState.asStateFlow()
型
在视图模型中,我通过交互器收集流。我在视图模型中的代码:
updateDepartmentsState.emitAll(
interactor
.updateState // state flow (`updateDepartmentsState` ) from repository via interactor
.map { state->
when (state) {
DepartmentFetchState.Loading -> {}
DepartmentFetchState.Error-> {}
...
}
}.also {
interactor.updateDepartments() // call updateDepartments() from repository via interator
}
型
我从文档中了解到,在我们完成收集之后,我们必须得到初始值。但是它没有发生。而且,我没有收到状态DepartmentFetchState.Loading
。我只收到最后一个状态-DepartmentFetchState.Success
。
但最有趣的是,如果我从视图模型重新调用代码(例如,当通过滑动更新时),那么我会得到DepartmentFetchState.Loading
状态,然后是DepartmentFetchState.Success
状态,正如预期的那样。
我不明白为什么在第一次调用时,初始化流时设置的初始值和DepartmentFetchState.Loading
状态丢失了。
请帮帮我(
3条答案
按热度按时间slsn1g291#
您所描述的是
StateFlow
的预期用途。此外,我没有接收到状态
DepartmentFetchState.Loading
。我只接收到最后一个状态-DepartmentFetchState.Success
。这是因为StateFlow是一个状态持有者可观察的流,它将当前和新的状态更新发送到它的收集器。当你开始收集流时,你的
updateDepartments()
已经完成了DepartmentFetchState.Success
。这意味着从你收集流的这一刻起,当前状态是DepartmentFetchState.Success
。然后:
但最有趣的是,如果我从视图模型重新调用代码(例如,当通过滑动更新时),那么我会得到
DepartmentFetchState.Loading
状态,然后是DepartmentFetchState.Success
状态,正如预期的那样。当您重新调用代码时,您会收到预期的结果,这是因为您在执行
updateDepartments()
时一直在从流中收集数据,它将分别发出当前状态DepartmentFetchState.Loading
和DepartmentFetchState.Success
。arknldoa2#
您可以在emit之后添加一个
yield()
,这将允许收集器运行它的collect
方法,如下所示:字符串
我不知道为什么你需要在你的情况下这样做,但是当你想以某种方式处理每个发射时,它是有用的,所以它确实有一个很好的用例。
只要知道任何处理都将被迫重新处理,可能不必要地使用这种方法。
cu6pst1q3#
这是因为StateFlow对值的更新总是合并的。如果值的发布速度比收集速度快,那么收集器只会得到最新的结果。
我觉得你有两个选择:
1.在更新后使用一点延迟,以确保它不会被跳过(* 不可靠 *)
1.使用
SharedFlow
代替,它不比较值并发出每个更新。