使用Rx更新金额

时间:2015-07-01 15:01:17

标签: reactive-programming rx-java rxjs

我有2个Subject(plusOne [itemId],minusOne [itemId]),它会发出项目ID,其中的金额应该被改变一个(加上或减去)。

用户可以发送具有相同项目ID的多个信号。最后,我想订阅Observable,发出Pair[itemId,amountToSet]

UI看起来像一个项目行列表,每个行包含“+”和“ - ”按钮,触发相应的onNext(itemId)。

我已经尝试过通过对itemid进行分组并减少序列来解决问题,但问题是reduce仅在调用onCompleted时启动,而我的主题不应该完成他们的排放量。

这是无法使用reduce的代码:

plusItem.asObservable().groupBy(id -> id).subscribe(new Action1<GroupedObservable<Long, Long>>() {
    @Override
    public void call(GroupedObservable<Long, Long> groupedObservable) {
        System.out.println("Composed a group with key: " + groupedObservable.getKey());
        groupedObservable
                .map(id -> 1)
                .startWith(0)
                .reduce((integer, integer2) -> integer + integer2)
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer sum) {
                        System.out.println(Integer.toString(sum));
                    }
                });
    }
});

解决方案

private Observable<Pair<Long,Integer>> getUpdateObservable(
    Observable clickSource,
        Observable<Map<Long,Integer>> initValues,
        Func1<Long,Integer> groupMapFunc

) {
    return clickSource
            .asObservable()
            .groupBy(id -> id)
            .flatMap(new Func1<GroupedObservable<Long, Long>, Observable<Pair<Long, Integer>>>() {
                @Override
                public Observable<Pair<Long, Integer>> call(GroupedObservable<Long, Long> groupedObservable) {
                    return groupedObservable
                            .map(groupMapFunc)
                            .scan((integer, integer2) -> integer + integer2)
                            .withLatestFrom(initValues, new Func2<Integer, Map<Long, Integer>, Integer>() {
                                @Override
                                public Integer call(Integer integer, Map<Long, Integer> basket) {
                                    return basket.get(groupedObservable.getKey()) + integer;
                                }
                            })
                            .map(new Func1<Integer, Pair<Long, Integer>>() {
                                @Override
                                public Pair<Long, Integer> call(Integer integer) {
                                    return new Pair<>(groupedObservable.getKey(), integer);
                                }
                            });
                }
            });
}

你能提出什么建议吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以使用scan将返回中间值

plusItem
  .asObservable()
  .groupBy(id -> id)
  .subscribe(new Action1<GroupedObservable<Long, Long>>() {
    @Override
    public void call(GroupedObservable<Long, Long> groupedObservable) {
        System.out.println("Composed a group with key: " + groupedObservable.getKey());
        groupedObservable
                .map(id -> 1)
                .scan(0, (integer, integer2) -> integer + integer2)
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer sum) {
                        System.out.println(Integer.toString(sum));
                    }
                });
    }
});