【问题标题】:How this change from runBlocking to sharedFlow work?这种从 runBlocking 到 sharedFlow 的改变是如何工作的?
【发布时间】:2022-12-06 00:09:25
【问题描述】:

我想问你为什么它有效? 通常当我使用collectLatestflow时,我的数据没有按时收集,返回值为空。我必须使用async-await协程,但我读过它会阻塞主线程,所以效率不高。我进行了研究并使用 sharedflow 找到了解决方案。

之前:

suspend fun getList: List<Items> {
    CoroutineScope(Dispatchers.Main).launch {
        async {
            flow.collectLatest {
                myItems = it
            }
        }.await()
    }
    return myItems
}

或者没有await-async,它返回emptyList

现在:

suspend fun getList: List<Items> {
    val sharedFlow = flow.conflate().shareIn(
         coroutineScopeIO,
         replay = 1,
         started = SharingStarted.WhileSubscribed()
    )
    return sharedFlow.first()
}

合并意味着:

Conflates flow emissions via conflated channel and runs collector in a separate coroutine. The effect of this is that emitter is never suspended due to a slow collector, but collector always gets the most recent value emitted.

我不确定我是否理解清楚。当我合并流程时,我只是创建单独的协程来发出我的另一个函数中的内容,如我的示例shareIn().first() 并使用这个暂停的变量sharedFlow,所以会产生与我所做的相同的效果asnyc-await,但在那种情况下我不会阻塞主线程,但只会阻塞我的确切*parentCoroutine-or-suspendFunction

SharingStarted.WhileSubscribed() 它只是意味着在订阅时开始发射。

【问题讨论】:

    标签: android kotlin kotlin-coroutines kotlin-stateflow kotlin-sharedflow


    【解决方案1】:

    conflate() 与此工作的原因无关。它谈到的独立协程在引擎盖下运行,您无需考虑它。这只是为了确保您的流程永远不会导致上游发射器不得不等待一个缓慢的收集器,并且如果它们的到来速度快于它可以处理的速度,您的收集器将跳过这些值。 conflate() 可以安全地使用没有缓冲区的慢速收集器。

    在您的第一个代码块中,您将在新的 CoroutineScope 中启动一个新的协程,因此它不是子协程,并且在函数返回之前不会等待。 (顺便说一句,这个新协程只会在 Flow 完成时完成,而大多数类型的 Flow 永远不会完成。)

    在第二个代码块中,您在 Flow 上调用 first(),它暂停并获取 Flow 发出的下一个值,然后返回该值而不等待 Flow 完成。


    其他一些注意事项:

    • 你永远不应该使用 async { /*...*/ }.await(),其中 await() 会在 Deferred 上立即调用,因为它只是 withContext(/*...*/) { /*...*/ } 的一个更复杂的版本。
    • 创建一个您永远不会分配给属性的 CoroutineScope 是一种代码味道,因为创建范围的目的是让您可以管理范围,如果您没有引用它,显然您就没有管理它一起工作。
    • 虽然您的代码有效,但在函数中创建 SharedFlow 并立即从中收集是没有意义的。它没有与任何东西共享!您的代码可以简化为以下等效代码:
    suspend fun getList: List<Items> {
        return flow.first()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 2014-12-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2013-10-28
      • 1970-01-01
      相关资源
      最近更新 更多