RxJava - Combining multiple/different web service calls

偶尔善良 提交于 2020-01-21 12:44:16

问题


I'm working with the Basecamp api to return and display to do lists. Here's a sample of what I'm doing at the moment:

bcxClient
  .fetchToDoLists()
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(new Action1<List<BcxToDoList>>() {
    @Override
    public void call(List<BcxToDoList> bcxToDoLists) {

      for( final BcxToDoList toDoList : bcxToDoLists ) {
        bcxClient
          .fetchToDos( toDoList.bucket.id )
          .subscribeOn( Schedulers.io() )
          .observeOn( AndroidSchedulers.mainThread() )
          .subscribe( new Action1<List<BcxToDo>>() {
            @Override
            public void call(List<BcxToDo> bcxToDos) {
              for( BcxToDo toDo : bcxToDos ) {
                toDoList.toDos.add( toDo );
              }
            }
          }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
              throwable.printStackTrace();
            }
          });
      }

      mLoremTextView.setText(bcxToDoLists.get(0).name);
    }

  }, new Action1<Throwable>() {
    @Override
    public void call(Throwable throwable) {
      throwable.printStackTrace();
    }
  });

fetchToDoLists and fetchToDos are Retrofit web service calls that return the BcxToDoList and BcxToDos Observables.

In the subscription to fetchToDoLists I loop through each BcxToDoList, call fetchToDos and attach my BcxToDo objects to the original list.

As you can see, it's a little verbose. I could just separate this into two statements to make it a little bit more readable. But, that's not very Rx. Is there a different way to do this in RxJava and improve its readability?

I could use lambdas to make this compact, but at this stage I'm more interested in what features in RxJava I could take advantage of.


回答1:


You should not "break the chain" in your RxJava calls, hence you will need flatMap to chain them. Also Observable.from() lets you split List of elements into separate Observables. Next, you can use toList to get elements back into list. Here's an example :

bcxClient
        .fetchToDoLists()
        .flatMap(new Func1<List<BcxToDoList>, Observable<BcxToDoList>>() {
            @Override
            public Observable<BcxToDoList> call(List<BcxToDoList> bcxToDoLists) {
                return Observable.from(bcxToDoLists);
            }
        })
        .flatMap(new Func1<BcxToDoList, Observable<List<BcxToDo>>>() {
            @Override
            public Observable<List<BcxToDo>> call(BcxToDoList bcxToDoList) {
                return bcxClient
                        .fetchToDos(bcxToDoList.bucket.id);
                        .map(new Func1<List<BcxToDo>, BcxToDoList>() {
                            @Override
                            public BcxToDoList call(List<BcxToDo> bcxToDos) {
                                bcxToDoList.toDos.addAll(bcxToDos);
                                return bcxToDoList;
                            }
                        });
            }
        })
        .toList()
        .subscribe(...);


来源:https://stackoverflow.com/questions/29140917/rxjava-combining-multiple-different-web-service-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!