Overview
From the Concatmap operation we know that the concat operator is definitely also ordered, and the concat operator is to receive a number of observables, the emission data is ordered, will not cross.
Using the example
Example One
The following example uses the concat operator to implement a multi-data source, such as a product detail needs to display information about a product, artist information, a product similar to that item, and may require access to three interfaces. You can use the concat operator at this time.
Seller Information
private Observable<Object> sellerInfo = Observable.create(new Observable.OnSubscribe<Object>() { @Override publicvoidcallsuper Object> subscriber) { Seller d = goodsApi.getSeller(); ifnull) { subscriber.onNext(d); } subscriber.onCompleted(); } }).subscribeOn(Schedulers.io());
Product Information
private Observable<Object> goodsInfo = Observable.create(new Observable.OnSubscribe<Object>() { @Override publicvoidcallsuper Object> subscriber) { Goods d = goodsApi.getGoodInfo(); ifnull) { subscriber.onNext(d); } subscriber.onCompleted(); } }).subscribeOn(Schedulers.io());
Similar works recommended
private Observable<Object> relateGoods = Observable.create(new Observable.OnSubscribe<Object>() { @Override publicvoidcallsuper Object> subscriber) { List<Goods> d = goodsApi.getRelateGoods(); ifnull) { subscriber.onNext(d); } subscriber.onCompleted(); } }).subscribeOn(Schedulers.io());
Observable.concat (Sellerinfo, Goodsinfo, Relategoods). Observeon (Androidschedulers.mainthread ()) . Subscribe (NewAction1<object> () {@Override Public void Pager(Object s) {Printlog (Tvlogs,"Getting data from", s);//push data to UI //for example:if (S instanceof User)} },NewAction1<throwable> () {@Override Public void Pager(Throwable throwable) {Throwable.printstacktrace (); Printlog (Tvlogs,"Error:", Throwable.getmessage ()); } });
Why generics are set to object, because Observable.concat only accepts parameters of the same generic type.
May be asked to obtain the product information when there is no way to pass the parameters AH (such as Product ID), the outer bread layer method can be, the method parameter is Goodid.
Example Two
The cache is checked using the concat operator, such as: Memory cache, local cache, network, and that layer has data immediately returned.
Use an array to represent three data sources:
String data[] = {null, null, "network"};//String data[] = {null, "disk", "network"};//String data[] = {"memory", null, "network"};//String data[] = {"memory", "disk",null};//String data[] = {"memory", "disk", "network"};
Memory Cache
private Observable<String> memorySource = Observable.create(new Observable.OnSubscribe<String>() { @Override publicvoidcallsuper String> subscriber) { String d = data[0]; """----start check memory data. value is null? "null)); ifnull) { subscriber.onNext(d); } subscriber.onCompleted(); } });
Local cache
private observable< string> Disksource = observable.create (new observable.onsubscribe<string > () { @Override public void call (subscriber<? super string> subscriber) {String d = data[1 ]; Printlog (tvlogs, , "----start check disk data. Value is NULL? " + (d = = null )); if (d! = null ) {Subscriber.onnext (d); } subscriber.oncompleted (); }}). Subscribeon (Schedulers.io ());
Network
private observable< string> Networksource = observable.create (new observable.onsubscribe< String> () { @Override public void call (subscriber<? super string> subscriber) {String d = data[2 ]; Printlog (tvlogs, , "----start check network data. Value is NULL? " + (d = = null )); if (d! = null ) {Subscriber.onnext (d); } subscriber.oncompleted (); }}). Subscribeon (Schedulers.io ());
From Example 1 we know that the concat will be requested by three data sources. How to make which layer has data to use which layer, then do not go behind the logic.
This effect can be achieved with the first () operator.
Observable.concat (Memorysource, Disksource, Networksource). First (). Observe On (Androidschedulers.mainthread ()). Subscribe (NewAction1<string> () {@Override Public void Pager(String s) {Printlog (Tvlogs,"Getting data from", s); } },NewAction1<throwable> () {@Override Public void Pager(Throwable throwable) {Throwable.printstacktrace (); Printlog (Tvlogs,"Error:", Throwable.getmessage ()); } });
It should be noted that if Memorysource, Disksource, networksource return null, then an exception will be reported:
Java.util.NoSuchElementException:Sequence contains no elements ...
You can use the Takefirst operation, which does not report an exception even if there is no data.
Observable.concat (Memorysource, Disksource, Networksource)//first (), if no data from observables would cause exception: //java.util.nosuchelementexception:sequence contains no elements //takefirst-no exception. Takefirst (NewFunc1<string, boolean> () {@Override PublicBooleanPager(String s) {returns! =NULL; }}). Observeon (Androidschedulers.mainthread ()). Subs Cribe (NewAction1<string> () {@Override Public void Pager(String s) {Printlog (Tvlogs,"Getting data from", s); } },NewAction1<throwable> () {@Override Public void Pager(Throwable throwable) {Throwable.printstacktrace (); Printlog (Tvlogs,"Error:", Throwable.getmessage ()); } });
Transferred from: http://blog.csdn.net/johnny901114/article/details/51568562
GitHub Source Download
RxJava concat operator processing multiple data sources