私はする必要があります:
たとえば、次の2つのオブザーバブルがあります。
Observable<RegionalNews> regionalNews;
Observable<NationalNews> nationalNews;
public interface NewsNationalService {
@GET("news/national")
Observable<News> getNationalNews();
}
public interface NewsRegionalService {
@GET("news/regional")
Observable<News> getRegionalNews();
}
組み合わせた結果で特定のことを実行したくない場合は、merge()で十分です。
Observable<RegionalNews> regionalNews = ...;
Observable<NationalNews> nationalNews = ...;
Observable
.merge(regionalNews, nationalNews)
.ignoreElements()
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> { /* show alert */ })
.subscribe()
Zip
演算子を使用して、2つのリクエストを非同期で呼び出し、応答時にそれらのデータを保存または処理できます。
例えば。
以下は2つのObservable
です
Observable<ResponseOne> responseOneObservable = getRetrofitClient().getDataOne()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
Observable<ResponseTwo> responseTwoObservable = getRetrofitClient().getDataTwo()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
上の2つのZip
でObservable
演算子を使用すると、次のようになります。
Observable<ArrayList<TestData>> testDataObservable = Observable.Zip(responseOneObservable, responseTwoObservable, new Func2<ResponseOne, ResponseTwo, ArrayList<TestData>>() {
@Override
public ArrayList<TestData> call(ResponseOne responseOne, ResponseTwo responseTwo) {
ArrayList<TestData> testDataList = new ArrayList();
// process data from response responseOne & responseTwo
return testDataList;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<ArrayList<TestData>>() {
@Override
public void onNext(ArrayList<TestData> testDataList) {
}
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted" );
// you can show alert here or do something when completed
}
@Override
public void onError(Throwable t) {
Log.d(TAG, "onError Throwable: " + t.toString() );
}
});
ええと、いつものように異なります。戻り値をチェーンで処理する必要がありますか、それとも単に保存する必要がありますか?
この実装では、SingleとCompletableを使用します。コンプリータブルをサブスクライブすると、両方のシングルが終了すると通知が届きます。
@Test
public void name() throws Exception {
TestScheduler testScheduler = new TestScheduler();
Single<Long> request1 = Single.timer(1000, TimeUnit.MILLISECONDS, testScheduler)
.doOnSuccess(aLong -> {
System.out.println("save to db.");
});
Single<Long> request2 = Single.timer(500, TimeUnit.MILLISECONDS, testScheduler)
.doOnSuccess(aLong -> {
System.out.println("save to db.");
});
Completable completable = Single.Zip(request1, request2, (aLong, aLong2) -> aLong).toCompletable();
TestObserver<Void> test = completable.test();
testScheduler.advanceTimeBy(1010, TimeUnit.MILLISECONDS);
test.assertComplete();
}
DoOnSuccessの代わりにflatMapCompletableを使用することもできます
@Test
public void name() throws Exception {
TestScheduler testScheduler = new TestScheduler();
Completable request1 = Single.timer(1000, TimeUnit.MILLISECONDS, testScheduler)
.flatMapCompletable(this::saveToDb);
Completable request2 = Single.timer(500, TimeUnit.MILLISECONDS, testScheduler)
.flatMapCompletable(this::saveToDb);
// need to cheat here, becuase completeable does not provide Zip
Completable completable = Single.Zip(request1.toSingle(() -> 1), request1.toSingle(() -> 1), (aLong, aLong2) -> aLong)
.toCompletable();
TestObserver<Void> test = completable.test();
testScheduler.advanceTimeBy(1010, TimeUnit.MILLISECONDS);
test.assertComplete();
}
private Completable saveToDb(long value) {
return Completable.complete();
}
Zip
はobservables
を組み合わせる方法です。結果を組み合わせることは単なる結果です。
両方のオブザーバブルが完了する(完了する)まで待機する場合、最も簡単な方法はZip
を使用することです。リクエストの結果を結合関数で使用する必要はありません。これらの両方の呼び出しが終了したときに別の何かを出力する方法として、この関数を使用してください。この関数がアイテムを発行するとき:
[...]すべてのリクエストが完了したときに何かを実行します(たとえば、アラートを表示します)
たとえば、次のようにします(これらの要求が両方とも完了したときにsomeOtherCall
を実行します):
Observable<Integer> obs1 = ...;
Observable<Long> obs2 = ...;
Observable.Zip(obs1, obs2, new Func2<Integer, Long, String>() {
@Override
public String call(Integer integer, Long aLong) {
return "something completely different";
}
}).flatMap(new Func1<String, Observable<Float>>() {
@Override
public Observable<Float> call(String s) {
return performSomeOtherCall();
}
}).subscribe(...);