【问题标题】:What does consuming a Kotlin Channel mean?使用 Kotlin Channel 是什么意思?
【发布时间】:2018-11-19 03:42:04
【问题描述】:
Kotlin 文档使用术语consume 来描述Channel#first() 等方法的行为以及Channel#consumeEach() 等方法的名称。
我很难理解频道消费与非消费的含义。
非消费到底是什么样的?
Channel API 是否允许在不消费的情况下访问通道中的项目?
除了consumeEach(),消费是否总是意味着完全清空一个频道?
【问题讨论】:
标签:
kotlin
channel
kotlinx.coroutines
【解决方案1】:
以下代码的输出说明了“消费”的含义和consumeEach的效果。
fun f1() = runBlocking {
val numbers = produce {
repeat(5) {
send(it)
delay(100)
}
}
run {
for (i in numbers) {
trace(i)
if (i == 2) return@run
}
}
trace("after run")
for (i in numbers) {
trace(i)
}
trace("exiting f1")
}
f1()
println()
fun f2() = runBlocking {
val numbers = produce {
repeat(5) {
send(it)
delay(100)
}
}
run {
numbers.consumeEach {
trace(it)
if (it == 2) return@run
}
}
trace("after run")
for (i in numbers) {
trace(i)
}
trace("exiting f2")
}
f2()
输出:
[main @coroutine#1]: 0
[main @coroutine#1]: 1
[main @coroutine#1]: 2
[main @coroutine#1]: after run
[main @coroutine#1]: 3
[main @coroutine#1]: 4
[main @coroutine#1]: exiting f1
[main @coroutine#3]: 0
[main @coroutine#3]: 1
[main @coroutine#3]: 2
[main @coroutine#3]: after run
[main @coroutine#3]: exiting f2
我们看到(在 f1 中)我们可以停止迭代通道,然后继续我们离开的地方。但是,当使用consumeEach(在 f2 中)时,我们无法停止和继续,即使通道最初能够产生大于 2 的数字。
【解决方案2】:
“consume”的使用意味着它是一个终端动作,这个命令之外的任何东西都不能从通道中读取。您可以在 first 和 consumeEach 的 API 文档中更清楚地看到这一点:
操作是终端。该函数消耗原始 ReceiveChannel 的所有元素。
请注意,文档中也有警告称此 API 将来会更改。
阅读KT-167 了解有关此主题的有用信息。