我希望将对象映射/转换为后台线程中的另一个对象,并在单个对话完成后立即将其置于主线程上。
Observable.just(1,2,3,4,5)
.map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
Log.d(TAG, "mapping number " + integer);
return String.valueOf(integer) + " mapped on: " + Thread.currentThread().getName();
}
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted on: " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String integer) {
Log.d(TAG, integer + " received on: "+ Thread.currentThread().getName());
}
});
结果是:
D: mapping number 1
D: mapping number 2
D: mapping number 3
D: mapping number 4
D: mapping number 5
D: 1 mapped on: RxNewThreadScheduler-1 received on: main
D: 2 mapped on: RxNewThreadScheduler-1 received on: main
D: 3 mapped on: RxNewThreadScheduler-1 received on: main
D: 4 mapped on: RxNewThreadScheduler-1 received on: main
D: 5 mapped on: RxNewThreadScheduler-1 received on: main
D: onCompleted on: main
但转换可能需要一段时间,我希望转换完成后立即收到。
D: mapping number 1
D: 1 mapped on: RxNewThreadScheduler-1 received on: main
D: mapping number 2
D: 2 mapped on: RxNewThreadScheduler-1 received on: main
D: mapping number 3
D: 3 mapped on: RxNewThreadScheduler-1 received on: main
D: mapping number 4
D: 4 mapped on: RxNewThreadScheduler-1 received on: main
D: mapping number 5
D: 5 mapped on: RxNewThreadScheduler-1 received on: main
D: onCompleted on: main
答案 0 :(得分:3)
无需设置全局缓冲区大小,只需使用observeOn(Scheduler, int)
重载,您可以将预取值指定为1.如果已处理前一个值,则只会询问下一个值。
答案 1 :(得分:0)
这是由于RxJava对您正在使用的链中的运算符施加背压。 ObserveOn等下游运营商通过数据块从上游请求数据,而不是通过单个项目来提高效率。如果将缓冲区大小设置为1,这将有效地实现您期望的效率成本:
-Drx.ring-buffer.size=1
具体而言,那对于有昂贵的往返电话的上游来说非常糟糕。
修改强>:
您可以使用带有BehaviorSubject的zip来排序下行和上行流的排序:
BehaviorSubject<Void> signal = BehaviorSubject.create();
signal.onNext(null); // <- pair up the signal with the first item immediately
Observable.just(1,2,3,4,5)
.zipWith(signal, (item,v)->item) //only emit a next item when there is a "receipt acknowledgement" from the down stream
.observeOn(Schedulers.newThread()) //<- needed to avoid fetching subsequent items in UI thread
.map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
Log.d(TAG, "mapping number " + integer);
return String.valueOf(integer) + " mapped on: " + Thread.currentThread().getName();
}
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted on: " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String integer) {
Log.d(TAG, integer + " received on: "+ Thread.currentThread().getName());
signal.onNext(null); //<- acknowledge receipt - allow emitting next item from upstream
}
});