编辑: 请注意,原回答中建议的API现在已被标记为@ObsoleteCoroutineApi
:
目前Ticker通道尚未与结构化并发集成,其API将来会有所改变。
您现在可以使用Flow
API创建自己的Ticker流:
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun tickerFlow(period: Duration, initialDelay: Duration = Duration.ZERO) = flow {
delay(initialDelay)
while (true) {
emit(Unit)
delay(period)
}
}
您可以以与当前代码非常相似的方式使用它:
tickerFlow(5.seconds)
.map { LocalDateTime.now() }
.distinctUntilChanged { old, new ->
old.minute == new.minute
}
.onEach {
setDateTime(it)
}
.launchIn(viewModelScope)
重要提示: 使用此处编写的代码时,tickerFlow
不会考虑处理元素所花费的时间,因此延迟可能不是固定的(这是元素处理之间的延迟)。如果您希望滚动新闻独立于每个元素的处理而运行,您可以使用buffer 或专用线程(例如通过 flowOn
)。
原始回答
我认为它仍处于实验阶段,但您可以使用TickerChannel每隔 X 毫秒生成一个值:
val tickerChannel = ticker(delayMillis = 60_000, initialDelayMillis = 0)
repeat(10) {
tickerChannel.receive()
val currentTime = LocalDateTime.now()
println(currentTime)
}
如果您需要在“tick”每次执行某些操作时继续工作,您可以启动
一个后台协程,该协程将从此通道读取并执行您想要的操作:
val tickerChannel = ticker(delayMillis = 60_000, initialDelayMillis = 0)
launch {
for (event in tickerChannel) {
val currentTime = LocalDateTime.now()
println(currentTime)
}
}
delay(1000)
tickerChannel.cancel()
如果你想在循环内部停止,你可以简单地跳出循环,然后取消通道:
val ticker = ticker(500, 0)
var count = 0
for (event in ticker) {
count++
if (count == 4) {
break
} else {
println(count)
}
}
ticker.cancel()