おそらく私はsubscribeOn
とobserveOn
の内部動作を理解しているかもしれませんが、最近私は本当に奇妙なことに遭遇しました。私は、subscribeOn
が最初に処理を開始するスケジューラを決定しているという印象を受けました。特にmap
が多くあり、observeOn
はスケジューラを変更するときにmaps
のどこでも使用できます最初にネットワーキングを行い、計算し、最後にUIスレッドを変更します。RxJava:subscribeOnとobserveOnが期待通りに動作しない
しかし、これらの呼び出しをObservableまたはSingleに直接連結しないと、動作しません。ここでは、最小限の作業例JUnitのテストです:
import org.junit.Test;
import rx.Single;
import rx.schedulers.Schedulers;
public class SubscribeOnTest {
@Test public void not_working_as_expected() throws Exception {
Single<Integer> single = Single.<Integer>create(singleSubscriber -> {
System.out.println("Doing some computation on thread " + Thread.currentThread().getName());
int i = 1;
singleSubscriber.onSuccess(i);
});
single.subscribeOn(Schedulers.computation()).observeOn(Schedulers.io());
single.subscribe(integer -> {
System.out.println("Observing on thread " + Thread.currentThread().getName());
});
System.out.println("Doing test on thread " + Thread.currentThread().getName());
Thread.sleep(1000);
}
@Test public void working_as_expected() throws Exception {
Single<Integer> single = Single.<Integer>create(singleSubscriber -> {
System.out.println("Doing some computation on thread " + Thread.currentThread().getName());
int i = 1;
singleSubscriber.onSuccess(i);
}).subscribeOn(Schedulers.computation()).observeOn(Schedulers.io());
single.subscribe(integer -> {
System.out.println("Observing on thread " + Thread.currentThread().getName());
});
System.out.println("Doing test on thread " + Thread.currentThread().getName());
Thread.sleep(1000);
}
}
テストnot_working_as_expected()
はworking_as_expected()
のに対し、出力
Doing some computation on thread main
Observing on thread main
Doing test on thread main
を以下の私を与え
Doing some computation on thread RxComputationScheduler-1
Doing test on thread main
Observing on thread RxIoScheduler-2
私にその最初のテストで唯一の違いを
を与え、単一の作成後にセミコロンがあり、それからスケジューラが適用され、実際の例ではメソッドコールはdirecですSingleの創造に結びついています。しかし、それは無関係ではないでしょうか?
これは非常によくある間違いです。各演算子は新しいオブジェクトを返します。 subscribeOn + observeOnを適用し、返されたSingleを無視し、元の変更されていないソースにサブスクライブします。 – akarnokd