如何等到所有视图模型异步操作完成
How to wait until all viewmodel asynchronous operations are done
我需要在完成所有异步提取后在我的视图中执行一些操作,为此我有一个家庭 framgnet,它在我的后端提取 3 个不同的部分
private fun populateSectionA(){
viewModel.fetchSectionA.observe(viewLifecycleOwner, Observer {
when(it){
is Resource.Loading -> { //Handling loading }
is Resource.Success -> {
//Handles data
}
is Resource.Failure -> { //Error handling }
}
})
}
private fun populateSectionB(){
viewModel.fetchSectionB.observe(viewLifecycleOwner, Observer {
when(it){
is Resource.Loading -> { //Handling loading }
is Resource.Success -> {
//Handles data
}
is Resource.Failure -> { //Error handling }
}
})
}
private fun populateSectionC(){
viewModel.fetchSectionC.observe(viewLifecycleOwner, Observer {
when(it){
is Resource.Loading -> { //Handling loading }
is Resource.Success -> {
//Handles data
}
is Resource.Failure -> { //Error handling }
}
})
}
这是我认为的观察者,我需要知道的是所有这 3 个何时完成加载我的 UI
从我的视图模型来看,三个部分的提取是相同的
val fetchSectionA = liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Resource.Loading())
try {
emit(repo.fetchSectionA(sectionId))
} catch (e: Exception) {
emit(Resource.Failure(e))
}
}
val fetchSectionB = liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Resource.Loading())
try {
emit(repo.fetchSectionB(sectionId))
} catch (e: Exception) {
emit(Resource.Failure(e))
}
}
val fetchSectionC = liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Resource.Loading())
try {
emit(repo.fetchSectionC(sectionId))
} catch (e: Exception) {
emit(Resource.Failure(e))
}
}
现在,我怎么知道所有这些单独的提取何时完成?我不想在我的 UI 中使用一个计数器,直到它达到一定数量,相反,我想在所有这些操作完成时给我的 UI 一个回调
如果您有以下代码:
fun <T1, T2, T3> combineTuple(f1: LiveData<T1>, f2: LiveData<T2>, f3: LiveData<T3>): LiveData<Triple<T1?, T2?, T3?>> = MediatorLiveData<Triple<T1?, T2?, T3?>>().also { mediator ->
mediator.value = Triple(f1.value, f2.value, f3.value)
mediator.addSource(f1) { t1: T1? ->
val (_, t2, t3) = mediator.value!!
mediator.value = Triple(t1, t2, t3)
}
mediator.addSource(f2) { t2: T2? ->
val (t1, _, t3) = mediator.value!!
mediator.value = Triple(t1, t2, t3)
}
mediator.addSource(f3) { t3: T3? ->
val (t1, t2, _) = mediator.value!!
mediator.value = Triple(t1, t2, t3)
}
}
那么你可以这样做:
combineTuple(fetchSectionA, fetchSectionB, fetchSectionC)
.map { (sectionA, sectionB, sectionC) ->
val sectionA = sectionA.takeIf { it != Resource.Loading } ?: return@map null
val sectionB = sectionB.takeIf { it != Resource.Loading } ?: return@map null
val sectionC = sectionC.takeIf { it != Resource.Loading } ?: return@map null
return Triple(sectionA, sectionB, sectionC)
}
如果您需要更多或更少的 LiveData 组合器,请检查 https://github.com/Zhuinden/livedata-combinetuple-kt
我需要在完成所有异步提取后在我的视图中执行一些操作,为此我有一个家庭 framgnet,它在我的后端提取 3 个不同的部分
private fun populateSectionA(){
viewModel.fetchSectionA.observe(viewLifecycleOwner, Observer {
when(it){
is Resource.Loading -> { //Handling loading }
is Resource.Success -> {
//Handles data
}
is Resource.Failure -> { //Error handling }
}
})
}
private fun populateSectionB(){
viewModel.fetchSectionB.observe(viewLifecycleOwner, Observer {
when(it){
is Resource.Loading -> { //Handling loading }
is Resource.Success -> {
//Handles data
}
is Resource.Failure -> { //Error handling }
}
})
}
private fun populateSectionC(){
viewModel.fetchSectionC.observe(viewLifecycleOwner, Observer {
when(it){
is Resource.Loading -> { //Handling loading }
is Resource.Success -> {
//Handles data
}
is Resource.Failure -> { //Error handling }
}
})
}
这是我认为的观察者,我需要知道的是所有这 3 个何时完成加载我的 UI
从我的视图模型来看,三个部分的提取是相同的
val fetchSectionA = liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Resource.Loading())
try {
emit(repo.fetchSectionA(sectionId))
} catch (e: Exception) {
emit(Resource.Failure(e))
}
}
val fetchSectionB = liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Resource.Loading())
try {
emit(repo.fetchSectionB(sectionId))
} catch (e: Exception) {
emit(Resource.Failure(e))
}
}
val fetchSectionC = liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Resource.Loading())
try {
emit(repo.fetchSectionC(sectionId))
} catch (e: Exception) {
emit(Resource.Failure(e))
}
}
现在,我怎么知道所有这些单独的提取何时完成?我不想在我的 UI 中使用一个计数器,直到它达到一定数量,相反,我想在所有这些操作完成时给我的 UI 一个回调
如果您有以下代码:
fun <T1, T2, T3> combineTuple(f1: LiveData<T1>, f2: LiveData<T2>, f3: LiveData<T3>): LiveData<Triple<T1?, T2?, T3?>> = MediatorLiveData<Triple<T1?, T2?, T3?>>().also { mediator ->
mediator.value = Triple(f1.value, f2.value, f3.value)
mediator.addSource(f1) { t1: T1? ->
val (_, t2, t3) = mediator.value!!
mediator.value = Triple(t1, t2, t3)
}
mediator.addSource(f2) { t2: T2? ->
val (t1, _, t3) = mediator.value!!
mediator.value = Triple(t1, t2, t3)
}
mediator.addSource(f3) { t3: T3? ->
val (t1, t2, _) = mediator.value!!
mediator.value = Triple(t1, t2, t3)
}
}
那么你可以这样做:
combineTuple(fetchSectionA, fetchSectionB, fetchSectionC)
.map { (sectionA, sectionB, sectionC) ->
val sectionA = sectionA.takeIf { it != Resource.Loading } ?: return@map null
val sectionB = sectionB.takeIf { it != Resource.Loading } ?: return@map null
val sectionC = sectionC.takeIf { it != Resource.Loading } ?: return@map null
return Triple(sectionA, sectionB, sectionC)
}
如果您需要更多或更少的 LiveData 组合器,请检查 https://github.com/Zhuinden/livedata-combinetuple-kt