我试图压缩两个在不同线程上发射的Observable:
Observable<String> xxxx1 = Observable.fromCallable((Func0<String>) () -> {
try {
Thread.sleep((long)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
return "First";
})
.doOnNext(s -> Log.d("TEEEST", "1 onNext " + s + " thread " + Thread.currentThread().getName()))
.subscribeOn(Schedulers.computation());
Observable<String> xxxx2 = Observable.fromCallable((Func0<String>) () -> {
try {
Thread.sleep((long)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Second";
})
.doOnNext(s -> Log.d("TEEEST", "2 onNext " + s + " thread " + Thread.currentThread().getName()))
.subscribeOn(Schedulers.io());
Observable.zip(xxxx1, xxxx2, (s1, s2) -> {
Log.d("TEEEST", "zip func thread " + Thread.currentThread().getName());
return s1.concat(s2);
})
.map(s -> {
Log.d("TEEEST", "map thread " + Thread.currentThread().getName());
return s.concat(" mapped");
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(s -> {
Log.d("TEEEST", "call " + s + " thread " + Thread.currentThread().getName());
});
似乎zip在作为最后一个发出值的线程上工作,这是我的日志的样子:
首先运行:
D/TEEEST: 2 onNext Second thread RxIoScheduler-3
D/TEEEST: 1 onNext First thread RxComputationScheduler-1
D/TEEEST: zip func thread RxComputationScheduler-1
D/TEEEST: map thread RxComputationScheduler-1
D/TEEEST: call FirstSecond mapped thread main
第二轮:
D/TEEEST: 1 onNext First thread RxComputationScheduler-2
D/TEEEST: 2 onNext Second thread RxIoScheduler-2
D/TEEEST: zip func thread RxIoScheduler-2
D/TEEEST: map thread RxIoScheduler-2
D/TEEEST: call FirstSecond mapped thread main
map
运算符)适用于特定的调度程序,而不是随机调度程序。答案 0 :(得分:4)
zip
不会在特定的Scheduler
上运行。
zip
只有在拥有所有要压缩的值时才会发出。所以它在它收到最后一个值的同一个线程上发出。
要确保在特定调度程序上执行所有下游操作,您必须定义observeOn()
副作用。
对于所有下游操作,观察压缩结果就足够了。
Observable.zip(...).observeOn(scheduler)
对于上游,您必须观察在此特定调度程序上压缩的观察者。
Observable.zip(o1.observeOn(scheduler), o2.observeOn(scheduler), ...)
根据您要使用的调度程序,这不保证线程。
答案 1 :(得分:0)
RXJava的优点在于RxJava中的操作符在等待来自上游可观察对象的值时阻塞线程,而不是保持线程和阻塞,运算符重用上游观察者向其发出值的线程。
行为不仅限于zip。您可以观察与其他运算符相同的行为,例如:flatMap。
从提供的池中挑选线程,因为它们可用。
答案 2 :(得分:0)
我想修改@ tynn&#39;在他的许可下,我的代码很少!
假设我想执行以下两个功能。
fetchFromGoogle = fetchFromGoogle.subscribeOn(Schedulers.newThread());
fetchFromYahoo = fetchFromYahoo.subscribeOn(Schedulers.newThread());
这样我们就可以使用#zip operator,
// Fetch from both API
Observable<String> zipped
= Observable.zip(fetchFromGoogle, fetchFromYahoo, new Func2<String, String, String>() {
@Override
public String call(String google, String yahoo) {
// Do something with the results of both threads
return google + "\n" + yahoo;
}
});
此外,您可以使用#concat运算符逐个运行该线程。
Observable<String> concatenated = Observable.concat(fetchFromGoogle, fetchFromYahoo);
// Emit the results one after another