繁体   English   中英

RxJava:缓冲项目,直到当前项目的某些条件为真

[英]RxJava: buffer items until some condition is true for current item

这是我想弄清楚的一个片段:

class RaceCondition {

    Subject<Integer, Integer> subject = PublishSubject.create();

    public void entryPoint(Integer data) {
        subject.onNext(data);
    }

    public void client() {
        subject /*some operations*/
                .buffer(getClosingSelector())
                .subscribe(/*handle results*/);
    }

    private Observable<Integer> getClosingSelector() {
        return subject /* some filtering */;
    }
}

有一个Subject接受来自外部的事件。 有一个客户订阅了这个主题,它处理事件并buffer它们。 这里的主要思想是每次都应该根据使用流中的项计算的某些条件来发出缓冲的项。

为此,缓冲区边界本身监听主题。

一个重要的期望行为:每当边界发出项目时,它也应该包含在buffer的以下发射中。 当前配置不是这样的项目(至少我认为是这样)在关闭选择器到达buffer 之前从关闭选择器发出,因此它不包含在当前发射中但是等待下一个发射。

有没有办法基本上使关闭选择器等待项目首先被缓冲? 如果没有,是否有另一种方法来缓冲和释放基于下一个传入项目的项目?

如果我理解正确,你想要缓冲,直到一些谓词允许它基于项目。 您可以使用一组复杂的运算符来完成此操作,但可能更容易编写自定义运算符:

public final class BufferUntil<T> 
implements Operator<List<T>, T>{

    final Func1<T, Boolean> boundaryPredicate;

    public BufferUntil(Func1<T, Boolean> boundaryPredicate) {
        this.boundaryPredicate = boundaryPredicate;
    }

    @Override
    public Subscriber<? super T> call(
            Subscriber<? super List<T>> child) {
        BufferWhileSubscriber parent = 
                new BufferWhileSubscriber(child);
        child.add(parent);
        return parent;
    }

    final class BufferWhileSubscriber extends Subscriber<T> {
        final Subscriber<? super List<T>> actual;

        List<T> buffer = new ArrayList<>();

        /**
         * @param actual
         */
        public BufferWhileSubscriber(
                Subscriber<? super List<T>> actual) {
            this.actual = actual;
        }

        @Override
        public void onNext(T t) {
            buffer.add(t);
            if (boundaryPredicate.call(t)) {
                actual.onNext(buffer);
                buffer = new ArrayList<>();
            }
        }

        @Override
        public void onError(Throwable e) {
            buffer = null;
            actual.onError(e);
        }

        @Override
        public void onCompleted() {
            List<T> b = buffer;
            buffer = null;
            if (!b.isEmpty()) {
                actual.onNext(b);
            }
            actual.onCompleted();
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM