合并多个单曲以形成一个可观察的

时间:2017-09-21 09:28:01

标签: android rx-java

我正在编写一个Android应用程序,需要按以下顺序执行2个查询:

  1. 向返回Single<List<String>> urls的库提出请求(让我们称之为RequestA)。
  2. 根据我从RequestA收到的内容,我必须使用这些网址向另一个库发出请求(RequestB)。每个RequestB现在都返回一个单独的。
  3. 现在我将所有RequestB中的所有Single组合成一个可观察的。

    Observable.mergedelayerror(List<Single>)这样的东西。我无法做到这一点,因为mergedelayerror期望iterable ObservableSource

    我知道我可以通过实现回调和使用一些丑陋的逻辑来实现这一目标但是我真的只使用RX提供的运算符来寻找解决方案

2 个答案:

答案 0 :(得分:3)

这是一个kotlin例子。 java版本几乎完全相同。您可能希望查看这些运算符的大理石图,以便在视觉上更容易看到正在发生的事情。

getData() //<--- original api call that returns a list of urls                                                                                                                                                   
     .flatMapObservable { list ->                                                                                                                                                                             
         //<- Since we are on a single we have to convert to an observable to emit each item onto the stream                                                                                                 
         Observable.fromIterable(list) // <-- create that observable that emits each item                                                                                                                     
     }                                                                                                                                                                                                        
     .flatMapSingle { url ->                                                                                                                                                                                  
         // we a single url entering here and have add it's result onto the stream but since it's a single we use flatMapSingle instead                                                                       
         secondApi(url) // we call our second api here                                                                                                                                                        
     }                                                                                                                                                                                                        
     .toList() // <-- you may want to group them into a list                                                                                                                                                  
     .subscribeOn(Schedulers.io()) // <-- causes the work to be done on the io scheduler so that you don't hit network on mainthread exception nor slow down the ui                                           
     .observeOn(AndroidSchedulers.mainThread()) // <-- causes the outcome to be on the ui thread so you can safely update without getting an illegal state exception can't update the ui from a now ui thread 
     .subscribe { next, error ->                                                                                                                                                                              
         next?.let {                                                                                                                                                                                          
             //add to an adapter or something else                                                                                                                                                              
         }
         error?.let{
             // handle error
         }                                                                                                                                                                                      
     }

答案 1 :(得分:2)

您需要Observable.fromIterable()。试试这个:

Java 8:

public interface Api {

    Single<List<String>> urls();

    Single<String> url(String url);
}

private Api api;

public void request() {
    api.urls()
            .flatMapObservable(Observable::fromIterable)//Observable<String>
            .flatMapSingle(api::url)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe();
}

非Java 8:

api.urls()
        .flatMapObservable(new Function<List<String>, ObservableSource<? extends String>>() {
            @Override
            public ObservableSource<? extends String> apply(@NonNull List<String> source) throws Exception {
                return Observable.fromIterable(source);
            }
        })
        .flatMapSingle(new Function<String, SingleSource<? extends String>>() {
            @Override
            public SingleSource<? extends String> apply(@NonNull String url) throws Exception {
                return api.url(url);
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe();

<强>科特林:

api.urls()
        .flatMapObservable { Observable.fromIterable(it) }
        .flatMapSingle { api.url(it) }
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe()

我建议使用Java 8或切换到Kotlin。它会更好用。