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);
    }

});