Rx java 对可观察对象发出的每个项目执行不同的并行操作
考虑以下示例Rx java 对可观察对象发出的每个项目执行不同的并行操作,rx-java,Rx Java,考虑以下示例 Observable.create(new Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> integerSubscriber) { for (int i = 1; i <= 10; i++) {
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> integerSubscriber) {
for (int i = 1; i <= 10; i++) {
integerSubscriber.onNext(i);
}
integerSubscriber.onCompleted();
}
}).parallel(new Func1<Observable<Integer>, Observable<Result>>() {
@Override
public Observable<Result> call(Observable<Integer> integerObservable) {
return integerObservable.flatMap(new Func1<Integer, Observable<Result>>() {
@Override
public Observable<Result> call(final Integer i) {
Result r = new Result();
r.i = i;
r.iSquare = i * i;
r.iQube = i * i * i;
return Observable.just(r);
}
});
}
}).subscribe(new Observer<Result> () {
@Override
public void onCompleted() {
System.out.println("Done.");
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
@Override
public void onNext(Result r) {
System.out.println(r.i + ", " + r.iSquare + ", " + r.iQube);
}
});
Observable.create(新建Observable.OnSubscribe()){
@凌驾
公共无效呼叫(订户一种可能的解决方案,我根据下面的kjones解决方案提出
final List<Result> results = new ArrayList<>();
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> integerSubscriber) {
for (int i = 1; i <= 10; i++) {
integerSubscriber.onNext(i);
}
integerSubscriber.onCompleted();
}
})
.parallel(new Func1<Observable<Integer>, Observable<Result>>() {
@Override
public Observable<Result> call(Observable<Integer> integerObservable) {
return integerObservable.flatMap(new Func1<Integer, Observable<Result>>() {
@Override
public Observable<Result> call(Integer i) {
System.out.println(Thread.currentThread().getName() + " processing " + i);
return Observable.zip(
Observable.just(i),
Observable.just(i)
.map(new Func1<Integer, Integer> () {
@Override
public Integer call(Integer i) {
System.out.println(Thread.currentThread().getName() + " squaring " + i);
sleep();
return i * i;
}
})
.subscribeOn(Schedulers.computation()),
Observable.just(i)
.map(new Func1<Integer, Integer> () {
@Override
public Integer call(Integer i) {
System.out.println(Thread.currentThread().getName() + " qubing " + i);
sleep();
return i * i * i;
}
})
.subscribeOn(Schedulers.computation()),
Observable.just(i)
.map(new Func1<Integer, Integer> () {
@Override
public Integer call(Integer i) {
System.out.println(Thread.currentThread().getName() + " 4th power " + i);
sleep();
return i * i * i * i;
}
})
.subscribeOn(Schedulers.computation()),
new Func4<Integer, Integer, Integer, Integer, Result> () {
@Override
public Result call(Integer i, Integer square, Integer qube, Integer fourth) {
System.out.println(Thread.currentThread().getName() + " combining results " + i + ", " + square + ", " + qube + ", " + fourth);
return new Result(i, square, qube, fourth);
}
});
}
});
}
})
.subscribe(new Observer<Result>() {
@Override
public void onCompleted() {
System.out.println(Thread.currentThread().getName() + " computed " + results);
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
@Override
public void onNext(Result r) {
results.add(r);
}
});
final List results=new ArrayList();
创建(新的Observable.OnSubscribe(){
@凌驾
公共无效呼叫(用户可观察
.范围(1,10)
.parallel(新函数1(){
@凌驾
公共可观测呼叫(可观测并行整数可观测){
最终可观测积分可观测=
并行整数可观测
.cache();
//Zip并行运行,但串行订阅每个订阅服务器。使用
//subscribeOn()方法强制每个计算运行异步。如果
//iSquare&iqbe当时正在长时间运行或阻塞操作
//可能不需要使用下面的subscribeOn()方法调用。
return-Observable.zip(
积分可观测,
积分可观测
.map(新函数1(){
@凌驾
公共整数调用(整数i){
返回i*i;
}
}),
积分可观测
.map(新函数1(){
@凌驾
公共整数调用(整数i){
返回i*i*i;
}
}),
新功能3(){
@凌驾
公共结果调用(整数i、整数iSquare、整数iqbe){
返回新结果(i、iSquare、iqbe);
}
}
);
}
})
.subscribeOn(Schedulers.computation())
.订阅(
//你的逻辑也一样。
);
编辑:由.parallel运算符创建的integerObservable似乎只能订阅一次(RxJava 0.20.0)。我修改了上面的代码,以缓存该可观察对象发出的整数,使其只有一个订阅方。以下代码是修改后的代码:
公共可观察调用(可观察并行整数可观察){
最终可观测积分可观测=
并行整数可观测
.cache();
在计算多维数据集后,integerObservable似乎已停止发出值。@GirishKolantha-由.parallel运算符创建的integerObservable似乎只能订阅一次(RxJava 0.20.0)。有关解决方案,请参见编辑。这似乎可行,但我注意到,即使在我将subscribeOn(Schedulers.computation())添加到传递到zip中的观察值之后,正方形和立方体也是在同一线程上计算的
public Observable<Result> call(Observable<Integer> integerObservable) {
return integerObservable.flatMap(new Func1<Integer, Observable<Result>>() {
@Override
public Observable<Result> call(final Integer i) {
Result r = new Result();
r.i = i;
r.iSquare = doOnParallelThread(i * i);
r.iQube = doOnParallelThread(i * i * i);
return Observable.just(r);
}
});
}
final List<Result> results = new ArrayList<>();
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> integerSubscriber) {
for (int i = 1; i <= 10; i++) {
integerSubscriber.onNext(i);
}
integerSubscriber.onCompleted();
}
})
.parallel(new Func1<Observable<Integer>, Observable<Result>>() {
@Override
public Observable<Result> call(Observable<Integer> integerObservable) {
return integerObservable.flatMap(new Func1<Integer, Observable<Result>>() {
@Override
public Observable<Result> call(Integer i) {
System.out.println(Thread.currentThread().getName() + " processing " + i);
return Observable.zip(
Observable.just(i),
Observable.just(i)
.map(new Func1<Integer, Integer> () {
@Override
public Integer call(Integer i) {
System.out.println(Thread.currentThread().getName() + " squaring " + i);
sleep();
return i * i;
}
})
.subscribeOn(Schedulers.computation()),
Observable.just(i)
.map(new Func1<Integer, Integer> () {
@Override
public Integer call(Integer i) {
System.out.println(Thread.currentThread().getName() + " qubing " + i);
sleep();
return i * i * i;
}
})
.subscribeOn(Schedulers.computation()),
Observable.just(i)
.map(new Func1<Integer, Integer> () {
@Override
public Integer call(Integer i) {
System.out.println(Thread.currentThread().getName() + " 4th power " + i);
sleep();
return i * i * i * i;
}
})
.subscribeOn(Schedulers.computation()),
new Func4<Integer, Integer, Integer, Integer, Result> () {
@Override
public Result call(Integer i, Integer square, Integer qube, Integer fourth) {
System.out.println(Thread.currentThread().getName() + " combining results " + i + ", " + square + ", " + qube + ", " + fourth);
return new Result(i, square, qube, fourth);
}
});
}
});
}
})
.subscribe(new Observer<Result>() {
@Override
public void onCompleted() {
System.out.println(Thread.currentThread().getName() + " computed " + results);
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
@Override
public void onNext(Result r) {
results.add(r);
}
});