假设我们有一个类似的Channel
private val channel = Channel<String>(1)
我们正在听像这样的Channel
元素
channel.receiveAsFlow().collect { myStr ->
println(myStr)
}
如果我运行这样的
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
...
fun sendMessage(myMessage: String) {
scope.launch {
channel.send(myMessage)
}
}
...
sendMessage("a")
sendMessage("b")
sendMessage("c")
sendMessage("d")
输出将是
a
b
c
d
现在,我试图实现的是,如果我发送"b"
,它会将通道中元素的处理延迟1秒。
例如,如果我做
...
sendMessage("a")
sendMessage("b")
sendMessage("c")
sendMessage("b")
sendMessage("d")
sendMessage("e")
我期望的输出会像一样
a // prints immediately
b // prints right after a
c // prints after 1 second
b // prints right after c
d // prints after 1 second
e // prints right after d
我的问题是,我将如何实现这种行为?我一直在尝试在这里和那里添加delay()
,但我没有任何运气。
这里有一个想法,但我觉得有点古怪。trySend
不适合这个。我不确定如何使trySend
符合您的标准,因为它应该立即返回一个关于值是否发布的结果。
这里,send()
暂停,直到可能的延迟结束。如果你不想等待,你就必须在每次发送东西时启动一个协同程序。
由于频道";构造函数";不是一个真正的构造函数,你不能将其子类化。我的解决方法是创建一个将其用作委托的类。
val backingChannel = Channel<String>(1)
val channel = object: Channel<String> by backingChannel {
var delayNext = false
val mutex = Mutex()
override suspend fun send(element: String) = mutex.withLock {
if (delayNext) {
delay(1000)
}
delayNext = element == "b"
backingChannel.send(element)
}
}