如何阅读Kotlin中Channel的所有可用元素

时间:2018-04-02 20:54:17

标签: kotlin

我想阅读一个频道中的所有可用元素,以便我可以对它们进行批量处理,如果我的接收器比我的发送者慢(希望处理批处理会更高效并允许接收者赶上) 。如果频道为空,我只想暂停,直到我的批量已满或暂停,而不是this question

标准kotlin库中是否有任何内容可以实现此目的?

2 个答案:

答案 0 :(得分:0)

我没有在标准的kotlin库中找到任何东西,但这是我想出来的。这将仅暂停第一个元素,然后poll所有剩余元素。这仅适用于Buffered Channel,以便准备好处理的元素排队并可用于poll

/**
 * Receive all available elements up to [max]. Suspends for the first element if the channel is empty
 */
internal suspend fun <E> ReceiveChannel<E>.receiveAvailable(max: Int): List<E> {
    if (max <= 0) {
        return emptyList()
    }

    val batch = mutableListOf<E>()
    if (this.isEmpty) {
        // suspend until the next message is ready
        batch.add(receive())
    }

    fun pollUntilMax() = if (batch.size >= max) null else poll()

    // consume all other messages that are ready
    var next = pollUntilMax()
    while (next != null) {
        batch.add(next)
        next = pollUntilMax()
    }

    return batch
}

答案 1 :(得分:0)

我测试了Jakes代码,它对我来说很好用(谢谢!)。没有最大限制,我将其归结为:

suspend fun <E> ReceiveChannel<E>.receiveAvailable(): List<E> {
    val allMessages = mutableListOf<E>()
    allMessages.add(receive())
    var next = poll()
    while (next != null) {
        allMessages.add(next)
        next = poll()
    }
    return allMessages
}