如何延迟我们发送到 Channel 的元素?
How to delay the elements the we send to a Channel?
假设我们有这样一个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
符合您的标准,因为它应该 return 立即得出有关值是否已发布的结果。
这里,send()
暂停,直到可能的延迟结束。如果您不想等待,则每次发送内容时都必须启动协程。
由于 Channel“构造函数”不是真正的构造函数,您不能将其子class。我的解决方法是创建一个将其用作委托的 class。
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)
}
}
假设我们有这样一个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
符合您的标准,因为它应该 return 立即得出有关值是否已发布的结果。
这里,send()
暂停,直到可能的延迟结束。如果您不想等待,则每次发送内容时都必须启动协程。
由于 Channel“构造函数”不是真正的构造函数,您不能将其子class。我的解决方法是创建一个将其用作委托的 class。
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)
}
}