RxJava Zwrócenie Single na podstawie kilku innych

0

Mam metodę która zwraca pewien obiekt (który jest Singlem z RX'a) na podstawie kilku zapytań z bazy danych. Wszystkie te metody zwracają Single i rezultatem też jest Single
Aktualnie wygląda to mniej więcej tak (piszę w Kotlinie ale nie ma to kompletnie znaczenia):

    api.getUser(id).flatMap { user -> 
            api.getAccesses(id).flatMap { accesses ->
                   api.getSomething(id).map { something ->
                           return Result(user, accesses, something)
                              

Tych zapytań jest więcej bo koło 10 więc tworzy się takie dość spore drzewo zagnieżdżeń i wygląda to mega słabo. Pomyślałem sobie że to przerobie na coś takiego:

    val user = api.getUser(id)
    val accesses =  api.getAccesses(id)
    val something =  api.getSomething(id)

    return //Co dalej??

I nie bardzo wiem jak dalej zwrócić jakiś Result. Wynikiem tej metody nadal ma być Single więc nie chcę tu żadnych bloków robić ale nie wiem jak to teraz posklejać. Jakieś rady?

0

Jakimś zipem nie da rady?

0

A nie jesteś wstanie tego przerobić, tak, żeby jednym zapytaniem wszystko dostać? Ewentualnie zebrać dane 'niżej' i zwrócić je jako jedno single już potem? ewentualnie coś pokombinować z then

1

Jednym ładnym chainem ciężko, bo z takim API z każdym zapytaniem tracisz wynik poprzedniego zapytania :p Jak masz te vary, to coś takiego jak Single.zip(user, access, something, funkcja_ktora_to_polaczy_w_nowego_singla) powinna ogarnąć

0

Nie jestem mistrzem Kotlina, ale zdaje się, że problem rozbija się o to, że Kotlin nie ma for comprehension
Są jakieś tricky na to i monady, ale czy to działą to nie wiem.
W Scali, która ma for comprehension można by napisać:

for {
  user <- api.getUser(id)
  accesses <-  api.getAccesses(id)
  something =  api.getSomething(id)
} yield Result(user, accesses, something)

Chociaż to tak naprawdę i tak jest tylko lukier składniowy i zostanie skompilowane do tej samej postaci którą napisałeś.

1
Kamil Żabiński napisał(a):

Nie jestem mistrzem Kotlina, ale zdaje się, że problem rozbija się o to, że Kotlin nie ma for comprehension
Są jakieś tricky na to i monady, ale czy to działą to nie wiem.
W Scali, która ma for comprehension można by napisać:

for {
  user <- api.getUser(id)
  accesses <-  api.getAccesses(id)
  something =  api.getSomething(id)
} yield Result(user, accesses, something)

Chociaż to tak naprawdę i tak jest tylko lukier składniowy i zostanie skompilowane do tej samej postaci którą napisałeś.

Wydaje się, że problemem nie jest brak for comprehension tylko fakt, że modelowane jest to za pomocą flatMap (czy to są monady spełniające prawa -> nie wiem), które definiują operacje w sposób sekwencyjny. To o co się pyta autor to jest zbiór wielu, niezależnych operacji więc Applicative. Czy te są dostępne w RxJava - nie mam pojęcia, nigdy się nie interesowałem, ale może warto poszukać w tym kierunku.

0
DisQ napisał(a):

To o co się pyta autor to jest zbiór wielu, niezależnych efektów więc Applicative.

Dokładnie tak.
W każdym razie problem solved.

Sam dopiero uczę się Rx'a ale wykorzystałem zip tak jak proponował @baant i wyszło coś na takiej zasadzie:

Single.zip(
    val user = api.getUser(id)
    val accesses =  api.getAccesses(id)
    val something =  api.getSomething(id)
   funkcjaKtoraSklejaResult
)

Póki co śmiga więc myślę że jest okej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1