RxJava:如何.zip两个Observable,然后.merge和最终.reduce汇总所有结果

时间:2015-05-04 12:28:28

标签: java rx-java

我有以下代码:

public void foo() {
    Long[] gData = new Long[] { 1L, 2L };

    rx.Observable.from(gData)
    .concatMap(data -> {

        rx.Observable<GmObject> depositObs1 = depositToUserBalance(data, 1);
        rx.Observable<GmObject> depositObs2 = depositToUserBalance(data, 2);


        return rx.Observable.zip(depositObs1, depositObs2, (depositObj1, depositObj2) -> {

            depositObj1.putNumber("seat_index", data);
            depositObj2.putNumber("seat_index", data);

            return rx.Observable.merge(
                    rx.Observable.just(depositObj1),
                    rx.Observable.just(depositObj2));
        })
    })
    .reduce(new ArrayList<Long>(), (payoutArr, payoutObj) -> {

        int seatIndex = ((GmObject) payoutObj).getNumber("seat_index").intValue();
        long payout = ((GmObject) payoutObj).getNumber("payout").longValue();
        payoutArr.add(seatIndex, payout);
        return payoutArr;
    })
    .subscribe(results -> {
        System.out.println(results);
    });
}

此代码使用.zip发送到observables,然后添加'seat_index'属性并调用.merge以使用.reduce,因此最终所有结果都会聚合到ArrayList中。

这段代码有一个问题:当.reduce处理它的输入时,它将它作为Observable而不是GmObject ...什么函数可以从它的Observable包装中“提取”GmObject?

以这种方式使用rxJava是否有意义?还是有更好的技术?

谢谢!

1 个答案:

答案 0 :(得分:6)

zip运算符将lambda作为第三个参数。这个lambda是一个2 args函数,它返回一个args组成的对象。而不是作为结果的Observable(当然,对象可以是Observable,但它不是你想要的那样)。

因此,在zip来电之后,您将获得Observable<Observable<GmObject>>,但预计会有Observable<GmObject>

我认为zip运算符不是您正在寻找的运算符。

public void foo() {
    Long[] gData = new Long[] { 1L, 2L };

    rx.Observable.from(gData)
    .concatMap(data -> {

        rx.Observable<GmObject> depositObs1 = depositToUserBalance(data, 1).doOnNext(obj -> obj.putNumber("seat_index", data));
        rx.Observable<GmObject> depositObs2 = depositToUserBalance(data, 2).doOnNext(obj -> obj.putNumber("seat_index", data));


        return rx.Observable.merge(depositObs1, depositObs2);
    })
   .reduce(new ArrayList<Long>(), (payoutArr, payoutObj) -> {

        int seatIndex = ((GmObject) payoutObj).getNumber("seat_index").intValue();
        long payout = ((GmObject) payoutObj).getNumber("payout").longValue();
        payoutArr.add(seatIndex, payout);
        return payoutArr;
   })
   .subscribe(results -> System.out.println(results));
}