ReactiveX emit null or sentinel value after timeout

前端 未结 2 1515
小鲜肉
小鲜肉 2020-12-20 21:05

Looking for a clean way to transform a source Observable to emit a single null (or sentinel value) after not emitting an item for some duration.

2条回答
  •  时光取名叫无心
    2020-12-20 21:47

    You can achieve this with a somewhat complicated publish-amb-timer setup:

    PublishSubject ps = PublishSubject.create();
    TestScheduler s = Schedulers.test();
    TestSubscriber ts = new TestSubscriber<>();
    
    ps.publish(o -> 
        o.take(1).ambWith(Observable.timer(10, TimeUnit.SECONDS, s).map(v -> (Integer)null))
        .repeat().takeUntil(o.ignoreElements())
    ).subscribe(ts);
    
    ps.onNext(1);
    ps.onNext(2);
    ps.onNext(3);
    
    s.advanceTimeBy(15, TimeUnit.SECONDS);
    
    ps.onNext(4);
    ps.onNext(5);
    ps.onNext(6);
    ps.onCompleted();
    
    ts.assertValues(1, 2, 3, null, 4, 5, 6);
    

    What happens is that the source is published so you can take items one by one from it or a timer event, make sure the fastest one wins and repeat it with the next value, all without resubscribing to the original source all the time.

    Edit fixed the case when the upstream completes the repeat() goes into an infinite loop.

提交回复
热议问题