Kotlin Flow - 收集时未收到一些发出的事件

标签 kotlin kotlin-coroutines kotlin-flow sealed-class kotlin-stateflow

我正在使用MutableStateFlow。我的流程类型是密封类,具有不同的状态(加载、成功、错误等)。我的流程的初始值为空:

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() 

在 View 模型中,我通过交互器收集流量。我在 View 模型中的代码:

 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

但最有趣的是,如果我从 View 模型重新调用代码(例如,通过滑动更新时),那么我会得到 DepartmentFetchState.Loading 状态,然后是DepartmentFetchState.Success 状态,如预期。

我不明白为什么在第一次调用时,初始化流程时设置的初始值和 DepartmentFetchState.Loading 状态会丢失。

请帮帮我(

最佳答案

您所描述的是StateFlow的预期目的。

Moreover, I do not receive state DepartmentFetchState.Loading. I receive only last state - DepartmentFetchState.Success.

这是因为 StateFlow 是一个状态持有者可观察流,它向其收集器发出当前和新的状态更新。当您开始收集流时,您的 updateDepartments() 已经完成了 DepartmentFetchState.Success。意味着从这一刻起,当您收集流量时,当前状态为 DepartmentFetchState.Success

然后:

But the most interesting thing is that if I re-call the code from the view model (for example, when updating by swipe), then I get the DepartmentFetchState.Loading state, and then the DepartmentFetchState.Success state, as expected.

当您重新调用代码时,您会收到预期的结果,这是因为您在 updateDepartments() 执行时一直在从流程中收集数据,它将发出当前状态 DepartmentFetchState。正在加载,然后分别是DepartmentFetchState.Success

关于Kotlin Flow - 收集时未收到一些发出的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71811835/

相关文章:

kotlin - 如何在kotlin中打印流的大小

java - 通过父类字段值对Jackson进行反序列化子类

android - 使用函数引用来注册和注销监听器是否安全?

kotlin - 协程中的 IO 会导致暂停吗?

android - 使用 Kotlin 协程进行实时 Firestore 更新

android - 使用 repeatOnLifeCycle 从 UI 中的 Flow 收集

android - debounce() Kotlin Flow 运算符不适用于每个新 Flow 创建,如何解决此问题?

kotlin - 如何合并两个对象列表并标识相同的元素

android - 我如何跳过除 Android 之外的所有目标,以便将多平台 Kotlin 库发布到 maven?

asynchronous - Kotlin 挂起函数递归调用