如何合并Kotlin协程中的生产者?

时间:2019-06-13 10:10:45

标签: kotlin kotlin-coroutines

使用Rx可以合并多个订阅源,如下所示

// psudo data repository

fun getAllData(): Flowable<DataType> {
    return getCachedData().mergeWith(getRemoteData())
}

fun getCachedData(): Flowable<DataType> {
    // local database call
}

fun getRemoteData(): Flowable<DataType> {
    // network call
}

以上getAllData()代码中的

将尽快返回合并的Flowables返回之一中的数据,然后在准备好后发送另一个。

问题是,如何使用Kotlin协程的produce获得相同的结果?

1 个答案:

答案 0 :(得分:1)

您可以使用produce创建一个组合通道,在其中启动两个协程,这些协程消耗两个输入通道并将其重新发送到该组合通道。

这是一个将多个相同类型的接收通道合并为一个接收通道的功能。

/**
 * Merges multiple [channels] into one channel.
 * All elements of all channels are send to the combined channel in the order they arrive on the input channels.
 */
fun <T> CoroutineScope.mergeChannels(vararg channels: ReceiveChannel<T>) : ReceiveChannel<T> {
    return produce {
        channels.forEach {
            launch { it.consumeEach { send(it) }}
        }
    }
}

您可以像这样使用它:

fun main() = runBlocking<Unit> {
    val every100Ms = produce {
        repeat(10) {
            send("every 100: $it")
            delay(100)
        }
    }

    val every200Ms = produce {
        repeat(10) {
            send("every 200: $it")
            delay(200)
        }
    }

    val combined = mergeChannels(every100Ms, every200Ms)
    combined.consumeEach { println(it) }
}