2017-02-23 159 views
1

Предположим, у меня есть служба для извлечения некоторых авторов (id, firstname, lastname, birthday, nationality) и вторая служба для извлечения авторской книги (название, резюме, количество страниц). Я бы хотел, чтобы мой сетевой звонок возвратил мне список авторов с их книгами.RXJava обработка вложенных вызовов

Чтобы проиллюстрировать, мои службы возвратят мне AuthorOResponse и BookResponse, и я хотел бы опубликовать Observable of AuthorObject.

public class AuthorResponse { 
    private String id; 
    private String firstname; 
    private String lastname; 
    private Date birthday; 
    private String nationality; 
} 

public class BookResponse { 
    private String title; 
    private String summary; 
    private int pageNumber; 
} 

public class AuthorObject { 
    private String id; 
    private String firstname; 
    private String lastname; 
    private Date birthday; 
    private String nationality; 
    private List<BookObject> books 
} 

Моих услуги будут нечто вроде

Observable<List<AuthorResponse>> getAuthors() 
Observable<List<BookResponse>> getAuthorBooks(String authorId) 

Я хотел бы использовать их, чтобы излучать наблюдаемом, но не могу понять, как это сделать, так как каждый из моих вызовов getAuthorBooks нужен автор.

Я придумал что-то похожее на это, но у меня есть проблема, так как моя concatMap делает меня «свободным» от моего автора.

myServices.getAuthors() 
       .map(author -> createAuthor()) 
       .concatMap(author -> mWebService.getAuthorBooks(author.getId()) 
       .flatMapIterable(data -> data.items) 
       .map(book -> addBook()) 

Кто-нибудь знает, как я мог это сделать?

ответ

5

Вы можете использовать special flatMap overload, предназначенные для таких случаев:

myServices.getAuthors() 
    .map(author -> createAuthor()) 
    .flatMap(author -> mWebService.getAuthorBooks(author.getId()), 
      (author, data) -> { 
       author.setBooks(data.items)); 
       return Observable.just(author); 
      }) 
    .toList() //here is your Observable<List<Author>> 
+1

Это кажется действительно замечательным. Поскольку я хочу испускать Observable , у меня будет flatMap, верните мой автор, но он работает хорошо. Спасибо! – Tibo

2

Может быть что-то вроде этого:

getAuthors.map(new Func1<List<AuthorResponse>, AuthorObject>() { 
     @Override 
     public AuthorObject call(List<AuthorResponse> authorResponses) { 
      return createAuthor(); 
     } 
    }).flatMap(new Func1<AuthorObject, Observable<AuthorObject>>() { 
     @Override 
     public Observable<AuthorObject> call(final AuthorObject authorObject) { 
      return getAuthorBooks(authorObject.id) 
        .map(new Func1<List<BookResponse>, AuthorObject>() { 
         @Override 
         public AuthorObject call(List<BookResponse> bookResponses) { 
          authorObject.books = parseBooks(bookResponses); 
          return authorObject; 
         } 
        }); 
     } 
    }); 

Query Авторы, сопоставьте каждый AuthorResponse к AuthorObject, а затем с помощью flatMap книг запросов для каждого Author и map это для того, чтобы добавить разобранные книги сгенерированного ранее AuthorObject. в конце вы получите Observable, который испускает AuthorObject с их книжным списком.

+0

Кажется, что работает на самом деле. Благодарю! – Tibo