RxJava(四) concatMap操作符用法詳解
阿新 • • 發佈:2019-01-10
RxJava系列文章目錄導讀:
concatMap操作符的作用
concatMap操作符和flatMap操作符非常類似。如果對 flatMap操作符 不是很瞭解可以點選連結去看看我的上一篇博文。下面是concatMap操作符的流程圖:
concatMap和flatMap最大的區別是concatMap發射的資料集是有序的,flatMap發射的資料集是無序的。
concatMap操作符的用法示例
通過上一篇對flatMap的介紹,我們的例子程式輸出的結果是無序的。現在把程式碼中的flatMap換成concatMap:
Observable.from(Arrays.asList(
"http://www.baidu.com/" ,
"http://www.google.com/",
"https://www.bing.com/"))
.concatMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String s) {
return createIpObservableMultiThread(s);
}
})
.observeOn(AndroidSchedulers.mainThread());
// 獲取ip
private synchronized Observable<String> createIpObservableMultiThread(final String url) {
return Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
try {
String ip = getIPByUrl(url);
printLog(tvLogs, "Emit Data -> ", url + "->" + ip);
subscriber.onNext(ip);
} catch (MalformedURLException e) {
e.printStackTrace();
//subscriber.onError(e);
subscriber.onNext(null);
} catch (UnknownHostException e) {
e.printStackTrace();
//subscriber.onError(e);
subscriber.onNext(null);
}
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io());
}
輸出結果:
Emit Data -> 'http://www.baidu.com/->115.239.211.112' , Main Thread:false, Thread Name:RxCachedThreadScheduler-1
Consume Data <- '115.239.211.112' , Main Thread:true, Thread Name:main
Emit Data -> 'http://www.google.com/->216.58.221.132'Main Thread:false, Thread Name:RxCachedThreadScheduler-3
Emit Data -> 'https://www.bing.com/->202.89.233.104' Main Thread:false, Thread Name:RxCachedThreadScheduler-2
Consume Data <- '216.58.221.132' Main Thread:true, Thread Name:main
Consume Data <- '202.89.233.104' Main Thread:true, Thread Name:main
輸出的結果始終都是baidu/google/bing, 使用的執行緒都是不同的執行緒。這也就解決了上篇部落格提出的問題:既要是多個執行緒完成任務,又要保持任務的順序
。
但是出現了一個奇怪的問題:上篇部落格我們使用flatMap在多個執行緒完成任務,有時候順序是亂的。但是concatMap一開始也是使用一個執行緒來完成任務,只有先呼叫flatMap多執行緒完成任務,然後再呼叫concatMap才會有多執行緒。
實驗結果表明:如果RxJava有了多個執行緒,concatMap才會使用多個執行緒,如果Rxjava裡只有一個快取的執行緒,concatMap只是用一個執行緒來執行任務,儘管加上了.subscribeOn(Schedulers.io())程式碼。然而如果是flatMap加上.subscribeOn(Schedulers.io())程式碼,每次呼叫都是多個執行緒的。這也是flatMap和concatMap的又一個區別。