当我在Kotlin中使用Flow时,我可以使用一个作业而不是两个作业吗?



在代码A中,有两个flow,我为它们分配了两个作业,我收集fun beginSoundDensity()中的两个flow,并停止收集fun resetSoundDensity()中的两个flow。

我认为代码A中有很多重复的代码,所以我希望改进,但是代码B不工作。

我可以在我的案例中使用一个Job吗?

代码

private val _soundDensityState = MutableStateFlow(initialMSoundDensity)
val soundDensityState = _soundDensityState.asStateFlow()
private val _timeX = MutableStateFlow(0)
val timeX = _timeX.asStateFlow()
private var myJob1: Job?=null
private var myJob2: Job?=null
val myFlow: Flow<Int> = flow {
var i = 0
while (true) {
emit(i)
i = i + 15
delay(5000)
}
}
fun beginSoundDensity() {
myJob1?.cancel()
myJob2?.cancel()
myJob1 = viewModelScope.launch {
aSoundMeter.startSoundDensity {
pauseSoundDensity()  
}.cancellable()
.collect {
_soundDensityState.value = it
}
}
myJob2 = viewModelScope.launch {
myFlow.collect {
_timeX.value = it
}
}
}
}
fun resetSoundDensity(){
myJob1?.cancel()
myJob2?.cancel()
}

代码B

//The same
private var myJob: Job?=null       
val myFlow: Flow<Int> = flow {
var i = 0
while (true) {
emit(i)
i = i + 15
delay(5000)
}
}
fun beginSoundDensity() {
myJob?.cancel()

myJob = viewModelScope.launch {
aSoundMeter.startSoundDensity {
pauseSoundDensity()  
}.cancellable()
.collect {
_soundDensityState.value = it
}
myFlow.collect {
_timeX.value = it      //It will not be launched
}
}

}
}
fun resetSoundDensity(){
myJob?.cancel()       
}

是,不是。需要同时运行两个独立的协程才能从两个流中收集数据。在你的代码B中,myFlow只有在aSoundMeter完成收集后才会被收集。集合需要同时运行,因此为此需要两个并发协程。

然而,如果你总是同时启动和取消两个集合,那么我认为最好将它们组合成一个协程,像这样:

fun beginSoundDensity() {
myJob?.cancel()

myJob = viewModelScope.launch {
coroutineScope {
launch {
aSoundMeter.startSoundDensity {
pauseSoundDensity()  
}.cancellable()
.collect {
_soundDensityState.value = it
}
}
launch {
myFlow.collect {
_timeX.value = it      //It will not be launched
}
}
}
}
}
fun resetSoundDensity(){
myJob?.cancel()       
}

最新更新