我正在编写一个Android应用程序,需要按以下顺序执行2个查询:
Single<List<String>> urls
的库提出请求(让我们称之为RequestA)。现在我将所有RequestB中的所有Single组合成一个可观察的。
像Observable.mergedelayerror(List<Single>)
这样的东西。我无法做到这一点,因为mergedelayerror
期望iterable
ObservableSource
。
我知道我可以通过实现回调和使用一些丑陋的逻辑来实现这一目标但是我真的只使用RX提供的运算符来寻找解决方案
答案 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。它会更好用。