Rxjava2方法类似于BiFunction

时间:2017-06-16 09:22:04

标签: java android rx-java rx-java2 sqlbrite

我用sqlbrite来监听表a和b的变化。并使用combineLatest运算符组合sqlbrite生成的observable。在BiFunction过程中,发出了observableA和observableB的项目。

private CompositeDisposable mSubscriptions = new CompositeDisposable();
private void initialize(){
    QueryObservable observableA = mDb.createQuery("table_a", "select * from table_a", null);
    QueryObservable observableB = mDb.createQuery("table_b", "select * from table_b", null);
    ResourceSubscriber subscriber = Flowable.combineLatest(
            RxJavaInterop.toV2Observable(observableA
                    .mapToList(mTableAMapperFunction)).toFlowable(BackpressureStrategy.LATEST)
            , 
            RxJavaInterop.toV2Observable(observableB
                    .mapToList(mTableBMapperFunction)).toFlowable(BackpressureStrategy.LATEST)
            , new BiFunction<List<ItemA>, List<ItemB>, List<ResultItem>>() {
                @Override
                public List<ResultItem> apply(@io.reactivex.annotations.NonNull List<ItemA> aItems, @io.reactivex.annotations.NonNull List<ItemB> bItems) throws Exception {
                    List<ResultItem> resultItems = convertToResultItems(aItems, bItems);    // long process here, convert aItems and bItems to resultItems
                    return resultItems;
                }
            }
    )
            .onBackpressureLatest()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(new ResourceSubscriber<List<ResultItem>>() {
                @Override
                public void onNext(List<ResultItem> resultItems) {
                    adapter.addData(resultItems);
                }

                @Override
                public void onError(Throwable t) {
                }

                @Override
                public void onComplete() {
                }
            });
    mSubscriptions.add(subscriber);
}

问题:如果BiFunction运行时间太长(例如10秒),比可观察的触发间隔时间长(例如每1秒触发一次可观测量),那将导致BiFunction不必要的工作因为我只需要最新发射的物品,但BiFunction会逐个处理发射的物品,因此BiFunction将处理旧的发射物品,我不需要处理它。 我希望BiFunction跳过旧的发射项并在BiFunction中每次完成apply()处理最新发射的项目,以减少资源浪费并节省时间。 rxjava的方法类似于BiFunction的背压或其他方法来解决这个问题吗?

该图显示了当前和预期的BiFunction时间轴。 figure link

我找到了两种方法来解决这个问题,但是存在缺陷。

方法1:结合&#34; aItems&#34;和&#34; bItems&#34;然后通过Pair将引用传递给switchMap并处理该作业。

缺陷:switchMap只向订阅者发送最新项目,但仍然做了不必要的工作。

方法2:还结合了&#34; aItems&#34;和&#34; bItems&#34;然后将引用传递给onNext并处理该作业。

缺陷:阻止了UI线程。

1 个答案:

答案 0 :(得分:0)

你可以在combineLatest的组合器函数中传递这对值,并使用observeOn将计算放在原始源线程之外:

 .combineLatest(srcA, srcB, (a, b) -> Pair.of(a, b))
 .onBackpressureLatest()
 .observeOn(Schedulers.computation(), false, 1)
 .map(pair -> compute(pair))
 .observeOn(AndroidSchedulers.mainThread())
 ...