为RxKotlin中的另一个Single <List>的所有元素获取Single <List>

时间:2019-10-21 19:07:28

标签: android rx-java reactive-programming rx-kotlin

A,B,C是物体

所有函数调用均指向Rooms DB

此代码段位于ViewModel内部

repo =存储库

因此,我正在制作一个android应用程序(无法提供详细信息),对于特定屏幕,我需要执行以下操作。

我的第一个调用是repo.getInfo,它返回一个Observable ListOfA:Single<List<A>> //执行一些操作

对于ListOfA的每个元素,我需要调用另一个函数repo.getB(A),该函数返回一个可观察的ListOfB:Single<List<B>> //执行一些操作

对于ListOfB的每个元素,我需要调用另一个函数repo.getC(B),该函数返回一个可观察的ListOfC:Single<List<C>> //执行一些操作

获得所需的数据后,我需要调用另一个将数据组合以显示在UI上的函数。

现在我无法使它正常工作。这是我尝试过的。但是流程在标记为THIS LINE的行处停止,并跳转到subscription块。 对函数的单独调用起作用,因此数据不是问题。 我在这方面还很陌生,坦白地说,我超出了我的深度。任何帮助或提示表示赞赏。谢谢

localListOfA = emptyList<A>()
localListOfB = emptyList<B>()
localListOfC = emptyList<C>()
compositeDisposable.add(
    getInfo.map{listOfA ->
        localListOfA.addAll(listofA)
        listOfA.map {elementA ->   ////THIS LINE
            getB(elementA.id).map{listOfB ->
                listOfB.filter {
                    //some logic to select a few objects
                }
            }.map { it // filtered list of B
                localListofB.addAll(it)
                localListOfB.last() //I only need the top element of this list
            }.map{elementB ->
                getC(elementB.id).map{ listOfC ->
                    localListOfC.addAll(listOfC)
                    //do some operations
                }
            }
        }
    }
    .subscribeOn(DEFAULT_CACHED_SCHEDULERS)
    .observeOn(AndroidSchedulers.mainThread())
    .doOnError(/*take log*/)
    .subscribe{
        prepareUi()
    }
)

1 个答案:

答案 0 :(得分:1)

您可以使用.flattenAsObservableList展平为Observable

getInfo // Single<List<A>>
    .doOnSuccess { localListOfA.addAll(it) } // Side effect, adding to localListOfA
    .flattenAsObservable { it } // Observable<A>
    .flatMapSingle { elementA -> getB(elementA.id) } // Observable<List<B>>
    .map { it.filter { true } } // Some logic to select a few objects from B
    .doOnNext { localListOfB.addAll(it) } // Side effect, adding to localListOfB
    .map { it.last() } // Observable<B>, only the last element
    .flatMapSingle { elementB -> getC(elementB.id) } // Observable<List<C>>
    .doOnNext { localListOfC.addAll(it) } // Side effect, adding to localListOfC
    .flatMapIterable { it } // Observable<C>

现在,您提到您需要以某种方式组合此数据。在Rx中,您可以嵌套链以访问中间数据。例如,如果您有一个返回Single<Foo>的调用,并且您需要Foo用于函数getBar(foo: Foo): Single<Bar>,则实现此目的的一种方法如下:

getFoo().flatMap { foo -> // .concatMap, .switchMap
    getBar(foo).map { bar ->
        // Use both foo and bar
    }
}