假设我在Observable上进行了一系列转换:
operation()
.flatMap(toSomething())
.map(toSomethingElse())
.flatMap(toYetSomethingElse())
.subscribeOn(Schedulers.newThread())
.observeOn(AdroidSchedulers.mainThread())
.subscribe(observer);
除了最后一次调用flatMap()
之外,所有这些操作是否都是同步的?或者所有操作都在我告诉它订阅的主题上运行?
答案 0 :(得分:1)
我通过测试想出了这一点。以下测试通过(这意味着Observable上的排放都在同一个后台线程上):
volatile long observableThreadId;
@Test
public void transformedObservables_shouldRunInSameThread() {
Observable.from(new String[]{"a", "b", "c"}) //
.flatMap(new Func1<String, Observable<Object>>() {
@Override public Observable<Object> call(String s) {
observableThreadId = Thread.currentThread().getId();
return Observable.from((Object) s);
}
}) //
.map(new Func1<Object, String>() {
@Override public String call(Object o) {
long id = Thread.currentThread().getId();
if (id != observableThreadId) {
throw new RuntimeException("Thread ID mismatch");
}
return (String) o;
}
}) //
.flatMap(new Func1<String, Observable<String>>() {
@Override public Observable<String> call(String s) {
long id = Thread.currentThread().getId();
if (id != observableThreadId) {
throw new RuntimeException("Thread ID mismatch");
}
return Observable.from(s);
}
}) //
.subscribeOn(Schedulers.newThread()) //
.observeOn(Schedulers.currentThread()) //
.subscribe(new Observer<String>() {
@Override public void onCompleted() {
assertThat(Thread.currentThread().getId()).isNotEqualTo(observableThreadId);
}
@Override public void onError(Throwable throwable) {
}
@Override public void onNext(String s) {
}
});
System.out.println("blah");
}
=============================== 更新:
实际上可以在Scheduler上的ReactiveX文档中找到更好的答案:
默认情况下,Observable和您应用的运算符链 它将完成其工作,并将在同一个线程上通知其观察员 在其上调用订阅方法。 SubscribeOn 运算符 通过指定其中的不同调度程序来更改此行为 观察应该运作。 ObserveOn 运算符指定了一个 Observable将用于发送通知的不同Scheduler 对观察员来说。
... SubscribeOn 运算符指定Observable将使用哪个线程 无论在运营商链中的哪个点,都要开始运营 该运算符被调用。另一方面, ObserveOn 影响了 Observable将使用 的线程,其中显示该运算符。 因此,您可以多次调用ObserveOn 在Observable运营商链中的点,以便改变 某些运营商运营的线程。