在”異步的世界“中經常會創(chuàng)建這樣的場景,我們有多個來源但是又只想有一個結果:多輸入,單輸出。RxJava的merge()方法將幫助你把兩個甚至更多的Observables合并到他們發(fā)射的數據項里。下圖給出了把兩個序列合并在一個最終發(fā)射的Observable。
http://wiki.jikexueyuan.com/project/rxjava/images/chapter6_1.png" alt="" />
正如你看到的那樣,發(fā)射的數據被交叉合并到一個Observable里面。注意如果你同步的合并Observable,它們將連接在一起并且不會交叉。
像往常一樣,我們用我們的App和已安裝的App列表來創(chuàng)建了一個“真實世界”的例子。為此我們還需要第二個Observable。我們可以創(chuàng)建一個單獨的應用列表然后讓它逆序排列。當然這沒有實際的意義,只是為了這個例子。對于第二個列表,我們的loadList()函數像下面這樣:
private void loadList(List<AppInfo> apps) {
mRecyclerView.setVisibility(View.VISIBLE);
List reversedApps = Lists.reverse(apps);
Observable<AppInfo> observableApps =Observable.from(apps);
Observable<AppInfo> observableReversedApps =Observable.from(reversedApps);
Observable<AppInfo> mergedObserbable = Observable.merge(observableApps,observableReversedApps);
mergedObserbable.subscribe(new Observer<AppInfo>(){
@Override
public void onCompleted() {
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(getActivity(), "Here is the list!", Toast.LENGTH_LONG).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(getActivity(), "One of the two Observable threw an error!", Toast.LENGTH_SHORT).show();
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onNext(AppInfoappInfo) {
mAddedApps.add(appInfo);
mAdapter.addApplication(mAddedApps.size() - 1, appInfo);
}
});
}
我們創(chuàng)建了Observable和observableApps數據項以及新的observableReversedApps逆序列表。使用Observable.merge(),我們可以創(chuàng)建新的Observable MergedObservable,它在單個可觀測序列中發(fā)射源Observables發(fā)出的所有數據。
正如你能看到的,每個方法簽名都是一樣的,因此我們的觀察者無需在意任何不同就可以復用代碼。結果如下: http://wiki.jikexueyuan.com/project/rxjava/images/chapter6_2.png" alt="" />
注意錯誤時的toast消息,你可以認為每個Observable拋出的錯誤都將會打斷合并。如果你需要避免這種情況,RxJava提供了mergeDelayError(),它能從一個Observable中繼續(xù)發(fā)射數據即便是其中有一個拋出了錯誤。當所有的Observables都完成時,mergeDelayError()將會發(fā)射onError(),如下圖所示:
http://wiki.jikexueyuan.com/project/rxjava/images/chapter6_3.png" alt="" />