8

一定期間アイテムを放出しなかった後Observable、単一の (またはセンチネル値) を放出するようにソースを変換するクリーンな方法を探しています。null

たとえば、ソースオブザーバブルが放出1, 2, 3し、放出する前に10秒間放出を停止する場合4, 5, 6、放出されるアイテムを1, 2, 3, null, 4, 5, 6.

使用例は、表示された値がダッシュに変わる場合、-またはN/A最後に発行された値が古い/古い場合に UI に値を表示するためです。

timeoutオペレーターを調べましたObservableが、タイムアウトが発生すると終了しますが、これは望ましくありません。

RxJava を使用します。

4

2 に答える 2

5

akarnokd の回答同様の質問の回答に基づいて、代替実装:

単一のセンチネル値 (OP による)

排出間の時間の経過を示す単一の値を探している場合:

final TestScheduler scheduler = new TestScheduler();
final TestSubject<Integer> subject = TestSubject.create(scheduler);
final TestSubscriber<Integer> subscriber = new TestSubscriber<>();

final long duration = 100;
final Observable<Integer> timeout = Observable.just(-1).delay(duration, TimeUnit.MILLISECONDS, scheduler)
    .concatWith(Observable.never())
    .takeUntil(subject)
    .repeat();

subject.mergeWith(timeout).subscribe(subscriber);

subject.onNext(1,   0);
subject.onNext(2, 100);
subject.onNext(3, 200);

scheduler.advanceTimeBy(200, TimeUnit.MILLISECONDS);
scheduler.advanceTimeBy(300, TimeUnit.MILLISECONDS);

subject.onNext(4,   0);
subject.onNext(5, 100);
subject.onNext(6, 200);

scheduler.advanceTimeBy(200, TimeUnit.MILLISECONDS);

subscriber.assertNoTerminalEvent();
subscriber.assertReceivedOnNext(Arrays.asList(1, 2, 3, -1, 4, 5, 6));

連続センチネル値

ソースオブザーバブルがしばらくの間放出されなかった後、継続的に値を受け取りたい場合:

final TestScheduler scheduler = new TestScheduler();
final TestSubject<Integer> subject = TestSubject.create(scheduler);
final TestSubscriber<Integer> subscriber = new TestSubscriber<>();

final long duration = 100;
final Observable<Integer> timeout = Observable.interval(duration, duration, TimeUnit.MILLISECONDS, scheduler)
    .map(x -> -1)
    .takeUntil(subject)
    .repeat();

subject.mergeWith(timeout).subscribe(subscriber);

subject.onNext(1,   0);
subject.onNext(2, 100);
subject.onNext(3, 200);

scheduler.advanceTimeBy(200, TimeUnit.MILLISECONDS);
scheduler.advanceTimeBy(300, TimeUnit.MILLISECONDS);

subject.onNext(4,   0);
subject.onNext(5, 100);
subject.onNext(6, 200);

scheduler.advanceTimeBy(200, TimeUnit.MILLISECONDS);

subscriber.assertNoTerminalEvent();
subscriber.assertReceivedOnNext(Arrays.asList(1, 2, 3, -1, -1, -1, 4, 5, 6));

違いはtimeout観察可能であり、それが繰り返されるかどうかです。

必要に応じて交換でき-1ますnull

上記のすべては、Java を使用して RxJava 1.0.17 でテストされています1.8.0_72

于 2016-04-15T01:42:38.360 に答える