繁体   English   中英

StateFlow 仅被众多收集器之一收集

[英]StateFlow only gets collected by one of many collectors

当用户被阻止时,我想通知我应用程序中的所有 ViewModels 事件。

我的用户状态:

    private val _refetchAllLists: MutableStateFlow<Boolean> = MutableStateFlow(false)
    val refetchAllLists: StateFlow<Boolean> = _refetchAllLists

   fun setRefetchAllLists(bool: Boolean){
        _refetchAllLists.value = bool
    }

这是我的存储库:

override fun refetchAllLists(): StateFlow<Boolean> {
    return userState.refetchAllLists
}

这就是我在所有 ViewModel 中收集它的方式:

init {
    viewModelScope.launch {
        repository.refetchAllLists().collect(){
            if(it){ 
            }
        }
    }
}

现在,每当用户被阻止时,我都会将 MutableStateFlow Boolean 设置为 true 但只有所有收集器中的一个(首先创建其视图模型的那个)会收到通知。

StateFlow 是合并的,这意味着收集器只会获取最新的值,如果没有及时收集,则可能会丢弃这些值。 由于您正在将其中一个收集器的值设置回false ,因此true值可能会在其他收集器看到它之前被丢弃。

如果您的目标是让所有收集者获得当且仅当他们在事件广播时订阅的事件,那么我认为您可以使用没有重放的SharedFlow<Unit>来实现。 我们可以将其设置为丢弃最旧的值,因为我们不关心在排放发生速度快于收集的情况下丢弃的值。 这将允许我们使用tryEmit()而没有发出刷新失败的风险。

private val _refetchAllLists: MutableSharedFlow<Unit> = 
    MutableSharedFlow(onBufferOverflow = BufferOverflow.DROP_OLDEST)
val refetchAllLists: StateFlow<Boolean> get() = _refetchAllLists

fun triggerRefetchAllLists() {
    _refetchAllLists.tryEmit(Unit)
}

您可能会考虑将此流程保密,并将其用作所有其他需要刷新的流程的基础。 那么你就不必从外部担心这一点。 如果你这样做,你应该给共享流replay 1 以确保总是有最初发出的东西。 是这样的:

private val refetchAllLists: MutableSharedFlow<Unit> = 
    MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST).apply {
        tryEmit(Unit) // seed with initial value
    }

// Change this:
fun getSomeRepoFlow(someId: Long): Flow<Something> =
    someApiFetch(someId)

// to this:
fun getSomeRepoFlow(someId: Long): Flow<Something> =
    refetchAllLists.flatMapLatest {
        someApiFetch(someId)
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM