也许我真的了解subscribeOn
和observeOn
的内部运作方式,但最近我遇到了一些非常奇怪的事情。我的印象是,subscribeOn
确定调度程序最初开始处理的位置(特别是当我们有很多map
更改数据流时),然后observeOn
可以在maps
之间的任何地方使用,以在适当时更改调度程序(首先进行网络连接,然后计算,最后更改UI线程)。
但是,我注意到,当没有直接将这些调用链接到我的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()
为我提供了以下输出
Doing some computation on thread main
Observing on thread main
Doing test on thread main
而working_as_expected()
给了我
Doing some computation on thread RxComputationScheduler-1
Doing test on thread main
Observing on thread RxIoScheduler-2
唯一的区别是,在第一个测试中,在创建单个元素之后有一个分号,然后才应用调度程序,并且在工作示例中,方法调用直接链接到Single的创建。但这不应该是无关紧要的吗?
答案 0 :(得分:3)
运营商执行的所有“修改”都是 不可变 ,这意味着它们会返回一个新流,该流以前一个方式更改的方式接收通知。由于您刚刚调用subscribeOn
和observeOn
运算符而未存储其结果,因此稍后进行的订阅将在未更改的流上进行。
一方注意:我不太了解您对subscribeOn
行为的定义。如果你的意思是地图运算符受某种程度的影响,那就不是这样了。 subscribeOn
定义了一个调度程序,在其上调用OnSubscribe函数。在您的情况下,您传递给create()
方法的函数。另一方面,observeOn
定义调度程序,每个连续流(应用运算符返回的流)处理来自上游的排放。
答案 1 :(得分:2)
.subscribeOn(*)
- 返回Observable
的新实例,但在第一次测试中,您只需忽略它,然后订阅原始Observable
,这显然默认订阅默认主线程。