我正在尝试使用流来编写秒表。
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking{
val startTime = System.currentTimeMillis()
val elapsedTime = MutableStateFlow(0L)
// start stopwatch
launch {
while(true){
elapsedTime.value = System.currentTimeMillis() - startTime
delay(100)
}
}
// update ui
launch {
elapsedTime.map{
it/1000
}.collect{
println("$it seconds")
}
}
}
0 seconds
0 seconds
0 seconds
0 seconds
0 seconds
0 seconds
0 seconds
0 seconds
0 seconds
0 seconds
1 seconds
1 seconds
1 seconds
问题是中间流不会像下面的代码一样跟踪值是否发生了变化:
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking{
val startTime = System.currentTimeMillis()
val elapsedTime = MutableStateFlow(0L)
// start stopwatch
launch {
while(true){
elapsedTime.value = (System.currentTimeMillis() - startTime)/1000
delay(5)
}
}
// update ui
launch {
elapsedTime.collect{
println("$it seconds")
}
}
}
0 seconds
1 seconds
2 seconds
3 seconds
我希望有一个单一的根流elapsedTime.value = System.currentTimeMillis() - startTime
,从中我可以有多个观察者,使用.map{it/a}
具有不同的精度水平。有没有一个干净的方法来实现这一点?
1条答案
按热度按时间cvxl0en21#
使用
distinctUntilChanged()
。作为创建流而不必使用MutableStateFlow的不同方法的示例,我使用了flow
构建器和stateIn
。另一种(我喜欢的)方法是在自己的协程中使用onEach
/launchIn
而不是collect
/launch
来收集流,以减少代码缩进和嵌套括号。