Kotlin 流程 - 流程是否为每个收集器创建一次?

Kotlin flow - Is flow created once for each collector?

我知道 Flowcold, and ShaerdFlow is hot

为了在 Kotlin 流程中测试冷流,我创建了以下代码。我的计划是,创建一个将发出 String 值的流并在其上添加两个收集器。我希望只有一个收集器会获得发射值,因为它是冷流。

但是结果不一样,我发现发出了两个值!

测试代码:

    val stringFlow: Flow<String> = flow<String> {
        for (i in 0..10) {
            Timber.d("Integer $i emitted ${currentCoroutineContext()}")
            emit("Integer $i")
            delay(500)
        }
    }
    // If I uncomment below line, only one flow will be emitted
    //.shareIn(coroutineScope, SharingStarted.Lazily) 


    val job1 = coroutineScope.launch {
        stringFlow.collect {
            Timber.d("job1 collect 1 $it")
        }
    }
    val job2 = coroutineScope.launch {
        stringFlow.collect {
            Timber.d("job2 collect 2 $it")
        }
    }

结果:

stringFlow: Integer 0 produced [StandaloneCoroutine{Active}@c2f624, Dispatchers.IO]
stringFlow: Integer 0 produced [StandaloneCoroutine{Active}@dd9f58d, Dispatchers.IO]
job1: job1 collect 1 Integer 0
job2: job2 collect 2 Integer 0

我该如何解释这种情况?我可以说“将为每个收集器创建一次流吗?”

是的,每当我们开始从中收集时,它就会开始发出新的 flow/stream 项。这在 documentation:

中有描述

The flow being cold means that the block is called every time a terminal operator is applied to the resulting flow.

其他冷流也是如此。例如,使用 flowOf() 创建的流在收集时发出相同的项目。每当我们收集时,使用 callbackFlow() 创建的流都会附加一个回调。等等。

I expect that the only one collector will get emitted value

如果您打算在多个消费者之间分配工作,那么我认为流不适合这种情况。它们更多地是关于观察事件或一些数据,而不是为了在多个生产者和消费者之间分配项目。请改用 channels