组合多个流量并在任何流动变化时发射

发布于 2025-02-04 05:07:21 字数 1356 浏览 4 评论 0原文

我很难理解为什么流动在我的应用中无法正常工作。

总共有三个流。前两个流都代表用户可以更改的单个值。它们用乘数式插曲保存,并定义如下。

fun flowA() = settings.getLongOrNullFlow(flowAKey).map { /* compute value */ }
fun flowB() = settings.getStringOrNullFlow(flowBKey).map { /* compute value */ }

第三个流是sqldelight查询,该查询取决于前两个流的值。目前,此流量如下。

fun flowC() = flowA().combine(flowB()) { (a, b) -> Pair(a, b) }
    .flapMapLatest { (a, b) ->
        queries.select(a, b).asFlow().mapToList().map { /* compute final value */ }
    }

当收集UI中的流量时,所有内容都按预期的是最初的发射,但不会随后发射。仅更改第一个或第二个流才会发出新值。当将条目添加到数据库中时,没有什么新发射(应该从sqldelight流量并传播)。看到这种变化的唯一方法是更新两个首先流中的任何一个,因此最后一个流程再次运行。

如何构造流程,以使sqldelight流程在接收新值时以及两个流程取决于更改时都会发出。

它可能与flatmaplatest有关,因为它仅在原始流动变化时会产生新的流程。但是我不确定如何在块中返回一些也会导致其发射的东西。

这就是最终在ViewModel中为UI收集的流程的方式。

class ViewModel(private val dataRepository: DataRepository) : ViewModel() {
    val data =
        dataRepository.flowC().stateIn(
            scope = viewModelScope,
            started = SharingStarted.Eagerly,
            initialValue = emptyList(),
        )
}

如果有什么尚不清楚的话。谢谢!

I'm having some trouble understanding why the flow isn't working as expected in my app.

There is three flows in total. The first two flows represents each a single value that can be changed by the user. They are saved with multiplatform-settings and defined as follows.

fun flowA() = settings.getLongOrNullFlow(flowAKey).map { /* compute value */ }
fun flowB() = settings.getStringOrNullFlow(flowBKey).map { /* compute value */ }

The third flow is a sqldelight query that is dependent on the values from the first two flows. This flow is currently defined as follows.

fun flowC() = flowA().combine(flowB()) { (a, b) -> Pair(a, b) }
    .flapMapLatest { (a, b) ->
        queries.select(a, b).asFlow().mapToList().map { /* compute final value */ }
    }

When collecting the flow in the UI everything works as expected for the initial emit but not subsequent emits. Only changes to the first or second flows emits new values. When an entry is added to the database is nothing new emitted (that should emit from the sqldelight flow and propagate). The only way to see that change is to update any of the two first flows so the last flows runs again.

How can the flows be constructed so that the sqldelight flow emits both when it receives new values and when the two flow it depends on changes.

It might have something to do with the flatMapLatest as it only produces a new flow when the original flow changes. But I'm not sure how to return something inside the block that would also cause it to emit.

This is how the flow is ultimately collected for the UI in a ViewModel.

class ViewModel(private val dataRepository: DataRepository) : ViewModel() {
    val data =
        dataRepository.flowC().stateIn(
            scope = viewModelScope,
            started = SharingStarted.Eagerly,
            initialValue = emptyList(),
        )
}

If anything is unclear just ask. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文