首页 > 解决方案 > flatMapMerge 缓存是否流动?

问题描述

我想知道 flatMapMerge 在这段代码中是如何工作的:

fun requestFlow(i: Int): Flow<String> = flow {
    emit("$i: First") 
    delay(500) // wait 500 ms
    emit("$i: Second")    
}

    fun main() = runBlocking<Unit> { 
        val startTime = System.currentTimeMillis() // remember the start time 
        (1..3).asFlow().onEach { delay(100) } // a number every 100 ms 
            .flatMapMerge { requestFlow(it) }                                                                           
            .collect { value -> // collect and print 
                println("$value at ${System.currentTimeMillis() - startTime} ms from start") 
            } 
    }

    1: First at 136 ms from start
    2: First at 231 ms from start
    3: First at 333 ms from start
    1: Second at 639 ms from start
    2: Second at 732 ms from start
    3: Second at 833 ms from start

休眠 500 毫秒后requestFlow,它继续emit("$i: **Second**")。看着输出,我很困惑。我的问题是

  1. flatMapMerge再次调用asFlow(1..3) 。或者
  2. 它是否在某处缓存 1..3 的流以供以后使用,因为requestFlow它告诉它,“我还没有完成”

标签: functionkotlin

解决方案


整个序列是这样的:

  • 1 从原始流发出并传递给requestFlow它创建一个新的流构建器,该构建器打印“1:首先在...”,然后暂停 500 毫秒。
  • 2 从原始流发出并传递给requestFlow它创建一个新的流构建器,它打印“2:首先在...”,然后暂停 500 毫秒。(这里我们在内存中有两个挂起的函数)。
  • 3 从原始流发出并传递给requestFlow它创建一个新的流构建器,该构建器打印“3:首先在...”,然后暂停 500 毫秒。(这里我们在内存中有三个挂起的函数)。
  • 从第一次发射开始 500 毫秒后,第一个挂起的函数恢复并打印“1: Second at ...”
  • 100ms 后,第二个函数恢复并打印“2: Second at ...”
  • 再过 100 毫秒后,最后一个挂起的函数恢复并打印“3: Second at ...”

flatternMapMerge只需应用您提供的转换并返回一个Flow<String>. 请注意,这不是挂起函数,因此会立即返回。

回答你的两个问题,

  • 不,asFlow不会再次调用该函数。
  • 它不是缓存流程,只是暂停功能 500 毫秒,直到那时才做其他事情,并在延迟结束后从中断的地方恢复。

推荐阅读