我有这个非常简单的RxJava示例
List<Integer> arrayIntegers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Observable.fromIterable(arrayIntegers).map(i -> {
Log.d("RxJava", "map i = " + i);
return i;
}).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).
subscribe(new DisposableObserver<Integer>() {
@Override
public void onNext(Integer i) {
Log.d("RxJava", "next i = " + i);
}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {
Log.d("RxJava", "Completed");
}
});
这给出了这个结果..
D/RxJava: map i = 1
D/RxJava: map i = 2
D/RxJava: map i = 3
D/RxJava: map i = 4
D/RxJava: map i = 5
D/RxJava: next i = 1
D/RxJava: next i = 2
D/RxJava: next i = 3
D/RxJava: next i = 4
D/RxJava: next i = 5
我期待的是更像这样的东西
D/RxJava: map i = 1
D/RxJava: next i = 1
D/RxJava: map i = 2
D/RxJava: next i = 2
D/RxJava: map i = 3
D/RxJava: next i = 3
D/RxJava: map i = 4
D/RxJava: next i = 4
D/RxJava: map i = 5
D/RxJava: next i = 5
有人可以解释我做错了什么导致我的订单不正确吗?
答案 0 :(得分:0)
您的Rx管道在两个不同的线程中运行。
第一个帖子(Schedulers.newThread()
)执行fromIterable
和map
。第二个调用DisposableObserver
。
在observeOn()
运算符内的两个线程之间有一个(不可见的)缓冲区。所以会发生的是第一个线程获得一些cpu时间,快速完成所有工作并将结果放入observeOn
缓冲区。这可能发生在CPU上该线程的单次旋转中。
然后,启动第二个线程,它从缓冲区获取项目并通过调用DisposableObserver
继续处理。
我认为您在这里寻找的是使用单个线程。删除observeOn
运算符,看它是否符合您的要求。
编辑:尝试删除observeOn
运算符并在我的计算机上运行它。结果如下:
RxJava map i = 1
RxJava next i = 1
RxJava map i = 2
RxJava next i = 2
RxJava map i = 3
RxJava next i = 3
RxJava map i = 4
RxJava next i = 4
RxJava map i = 5
RxJava next i = 5
为了将来参考,可能有助于调试目的来打印到达各种Rx运算符的线程的名称。您可以使用Thread.currentThread().getName()
获取名称。