使用 Flow、StateFlow、SharedFlow 发出值时避免重复启动
Avoid repetitive launch when emitting value using Flow, StateFlow, SharedFlow
我正在从 LiveData
迁移到协程流,特别是 StateFlow
和 SharedFlow
。不幸的是,在 CoroutineScope 上发出的值应该 运行 因此当在 ViewModel 中使用它时你会得到这个难看的重复代码 viewModelScope.launch
。是否有最佳的方法来从中发出值?
class MainSharedViewModel : BaseViewModel() {
private val mainActivityState = MutableSharedFlow<MainActivityState>()
fun getMainActivityState(): SharedFlow<MainActivityState> = mainActivityState
fun setTitle(title: String){
viewModelScope.launch {
mainActivityState.emit(ToolbarTitleState(title))
}
}
fun filterData(assetName: String){
viewModelScope.launch {
mainActivityState.emit(AssetFilterState(assetName))
}
}
fun limitData(limit: Int){
viewModelScope.launch {
mainActivityState.emit(AssetLimitState(limit))
}
}
}
使用 tryEmit()
而不是 emit()
。 tryEmit()
是 non-suspending。它是“尝试”的原因是,如果流的缓冲区当前已满并设置为 SUSPEND 而不是在满时丢弃值,它不会发出。
请注意,您当前没有缓冲区,因为您将 replay
保留为 0。您应该至少保留 1
的重放,这样当您的配置发生更改时不会丢失值Activity/Fragment.
示例:
fun setTitle(title: String){
mainActivityState.tryEmit(ToolbarTitleState(title))
}
或者,您可以使用 MutableStateFlow,它的重播始终为 1,并且可以使用 value =
设置其值,就像 LiveData 一样。
我正在从 LiveData
迁移到协程流,特别是 StateFlow
和 SharedFlow
。不幸的是,在 CoroutineScope 上发出的值应该 运行 因此当在 ViewModel 中使用它时你会得到这个难看的重复代码 viewModelScope.launch
。是否有最佳的方法来从中发出值?
class MainSharedViewModel : BaseViewModel() {
private val mainActivityState = MutableSharedFlow<MainActivityState>()
fun getMainActivityState(): SharedFlow<MainActivityState> = mainActivityState
fun setTitle(title: String){
viewModelScope.launch {
mainActivityState.emit(ToolbarTitleState(title))
}
}
fun filterData(assetName: String){
viewModelScope.launch {
mainActivityState.emit(AssetFilterState(assetName))
}
}
fun limitData(limit: Int){
viewModelScope.launch {
mainActivityState.emit(AssetLimitState(limit))
}
}
}
使用 tryEmit()
而不是 emit()
。 tryEmit()
是 non-suspending。它是“尝试”的原因是,如果流的缓冲区当前已满并设置为 SUSPEND 而不是在满时丢弃值,它不会发出。
请注意,您当前没有缓冲区,因为您将 replay
保留为 0。您应该至少保留 1
的重放,这样当您的配置发生更改时不会丢失值Activity/Fragment.
示例:
fun setTitle(title: String){
mainActivityState.tryEmit(ToolbarTitleState(title))
}
或者,您可以使用 MutableStateFlow,它的重播始终为 1,并且可以使用 value =
设置其值,就像 LiveData 一样。