RXJava PausableBuffer

时间:2016-04-03 12:07:21

标签: java rx-java

嗨,我是RXJava的新手。 我正在寻找一种可观察的解决方案,该解决方案将根据收到的项目继续并暂停发出项目。

假设我们的条件是整数谓词:

Func1<Integer, Boolean> isOdd = number -> number%2==1;

当我们向Subject添加数字时如:myNumberSubject.onNext(someInt);所有在添加奇数之前添加的数字都存储在缓冲区中,但是添加了第一个奇数的数字,缓冲区中的所有数字都是一次爆发(包括奇怪的物品)。

之后,每个数字都是一个接一个地发出,只要它是奇数。当添加偶数时,它再次被放入缓冲区。

我找不到任何真正有效的例子,但是这个大理石pausableBuffer的例子有可能完全符合我的要求。 http://rxmarbles.com/#pausableBuffered 我希望有一些预先存在的RXJava解决方案可以解决这个问题。这是我自己的黑客工作解决方案。

public class PausableBuffer<R> {

    private boolean isPaused;
    private List<R> buffer;
    private ReplaySubject<R> regulatedSubject;

    private PausableBuffer(){
        regulatedSubject = ReplaySubject.create();
        buffer=new LinkedList<>();
    }

    public static <R>Observable<R> create(Observable<R> observable, Func1<R, Boolean> continueCondition){
        PausableBuffer<R> pausableBuffer = new PausableBuffer<>();
        observable.subscribe(value -> {
            synchronized(pausableBuffer) {
                if(pausableBuffer.isPaused){
                    pausableBuffer.buffer.add(value);
                    if(continueCondition.call(value)){
                        pausableBuffer.isPaused=false;
                        for (R r : pausableBuffer.buffer) {
                            pausableBuffer.regulatedSubject.onNext(r);
                        }
                        pausableBuffer.buffer.clear();
                    }
                }else{
                    if(continueCondition.call(value)){
                        pausableBuffer.regulatedSubject.onNext(value);
                    }else{
                        pausableBuffer.isPaused=true;
                        pausableBuffer.buffer.add(value);
                    }
                }
            }
        });
        return pausableBuffer.regulatedSubject.asObservable();
    }

    public static void main(String[] args) {
        BehaviorSubject<Integer> behaviorSubject = BehaviorSubject.create();
        Observable<Integer> observable = PausableBuffer.<Integer>create(
                behaviorSubject.asObservable(),                    
                intValue -> intValue==5 || 6<intValue);//continueCondition
        observable.subscribe(v -> System.out.print(v+", "));
        for (int i = 0; i <= 8; i++) {
            System.out.print("adding " + i + " : ");
            behaviorSubject.onNext(i);
            System.out.println();
        }
    }
}

打印出来:

  • 添加0:
  • 添加1:
  • 添加2:
  • 添加3:
  • 添加4:
  • 添加5:0,1,2,3,4,5,
  • 添加6:
  • 添加7:6,7,
  • 添加8:8,

1 个答案:

答案 0 :(得分:0)

第二版:

public final class ContinueWhile<T> implements Observable.Operator<T, T> {

final Func1<T, Boolean> continuePredicate;

private ContinueWhile(Func1<T, Boolean> continuePredicate) {
    this.continuePredicate = continuePredicate;
}

public static <T>ContinueWhile<T> create(Func1<T, Boolean> whileTrue){
    return new ContinueWhile<>(whileTrue);
}

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

final class ContinueWhileSubscriber extends Subscriber<T> {

    final Subscriber<? super T> actual;
    Deque<T> buffer = new ConcurrentLinkedDeque<>();

    public ContinueWhileSubscriber(Subscriber<? super T> actual) {
        this.actual = actual;
    }

    @Override
    public void onNext(T t) {
        buffer.add(t);
        if (continuePredicate.call(t)) {
            while(!buffer.isEmpty())
                actual.onNext(buffer.poll());
        }
    }

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

    @Override
    public void onCompleted() {
        while (!buffer.isEmpty())
            actual.onNext(buffer.poll());
        buffer=null;
        actual.onCompleted();
    }
}
}




public static void main(String[] args) {
    BehaviorSubject<Integer> subject = BehaviorSubject.create();
    subject.asObservable()
            .doOnNext(v -> System.out.print("next "))
            .lift(ContinueWhile.create(i -> i%3==0))
            .subscribe(v -> System.out.print(v + ", "));
    for (int i = 0; i < 10; i++) {
        subject.onNext(i);
    }
}
}

感谢AndroidEx。