假设我有一个Flowable<Integer> sequence
,它发出编码事件。另一个Flowable<Boolean> task
需要延迟,直到sequence
发出特定序列为止(例如1
,2
,3
)。我该怎么办?
当前,我将task
的flowable延迟到发出某个值之前,就像这样:
task = task.delaySubscription(sequence.filter(i -> i == 42));
我尝试使用buffer(3)
完成此操作,但是如果发射值的总数不能被3整除,则该方法不起作用。
task = task.delaySubscription(sequence.buffer(3).filter(vals -> vals.get(0) == 1 && vals.get(1) == 2 && vals.get(2) == 3));
// This fails
sequence.onNext(42);
sequence.onNext(1);
sequence.onNext(2);
sequence.onNext(3);
task.test().assertValueCount(1).assertValue(true);
// While this works
sequence.onNext(1);
sequence.onNext(2);
sequence.onNext(3);
task.test().assertValueCount(1).assertValue(true);
我需要同时处理这两种情况;唯一重要的是最近发射的三个物品。
答案 0 :(得分:0)
也许通过实现自定义过滤器?
private static class SequencePredicate implements Predicate<Integer> {
private final List<Integer> searchedSequence;
private LinkedList<Integer> remaining;
private SequencePredicate(final List<Integer> searchedSequence) {
this.searchedSequence = searchedSequence;
this.remaining = new LinkedList<>(searchedSequence);
}
@Override
public boolean test(final Integer integer) throws Exception {
boolean result = false;
if (remaining.isEmpty()) {
result = true;
} else if (remaining.getFirst().equals(integer)) {
remaining.removeFirst();
result = remaining.isEmpty();
} else if (remaining.size() < searchedSequence.size()) {
remaining = new LinkedList<>(searchedSequence);
}
return result;
}
}
public static void main(String[] args) {
Flowable<Integer> sequence = Flowable.just(3, 5, 1, 2, 6, 1, 2, 3, 8, 9);
// Flowable<Integer> sequence = Flowable.just(3, 5, 1, 2, 6, 1, 2, 8, 9, 10);
List<Integer> searchedSequence = Arrays.asList(1, 2, 3);
Flowable<Integer> delayFlowable = sequence.doOnNext(n -> System.out.println("before: " + n))
.filter(new SequencePredicate(searchedSequence))
.doOnNext(n -> System.out.println("after: " + n));
Flowable<Boolean> task = Flowable.just(true);
task.delaySubscription(delayFlowable)
.subscribe(n -> System.out.println("task: " + n),
Throwable::printStackTrace,
() -> System.out.println("task: that's the end!"));
Flowable.timer(10, SECONDS) // just for blocking the main thread
.blockingSubscribe();
}