热观测值的RxJava延迟

时间:2017-11-07 11:48:11

标签: java rx-java delay

我看到了这个问题here。 这是关于实现每个发射物品的延迟。这是基于accepted answer

实现它的方法
Observable.zip(Observable.range(1, 5)
    .groupBy(n -> n % 5)
    .flatMap(g -> g.toList()),
Observable.interval(50, TimeUnit.MILLISECONDS),
(obs, timer) -> obs)
.doOnNext(item -> {
  System.out.println(System.currentTimeMillis() - timeNow);
  System.out.println(item);
  System.out.println(" ");
}).toList().toBlocking().first();

在问题中,提问者明确要求一组固定的可观察量(Observable.range(1,5)),遗憾的是这不是我想要实现的目标。

我也看到了comment

这个评论是我想要实现的。所以我的source observable以比间隔更慢(有时更快)的速率发出项目。此外,观察者的发出也永无止境。

===

所以基本上我希望热观察者有最小的延迟。

例如,如果我想要400ms的最小延迟并且我有这种可观察的发射率:

  

X1-100ms延迟-X2-200ms延迟-X3-600ms延迟-X4-20000ms延迟-X5 -...

我希望它能够产生:

  

X1-400ms延迟-X2-400ms延迟-X3-600ms延迟-X4-20000ms延迟-X5 -...

有人有任何想法实现这一目标吗?

1 个答案:

答案 0 :(得分:1)

你的要求太奇怪了......

我可以解决但不优雅。这是我的代码:

class Three<A, B, C> {
    A a;
    B b;
    C c;
    // Getter, Setter, Constructor
  }

  public static void main(String[] args) throws Exception {
    BehaviorSubject<Integer> s = BehaviorSubject.create();
    // Three = (The value, upstream comes mills, downstream emits mills)
    s.map(i -> new Three<>(i, System.currentTimeMillis(), System.currentTimeMillis()))
        .scan((a, b) -> {
          b.setC(a.getC() + Math.max(400L, b.getB() - a.getB()));
          return b;
        })
        .concatMap(i -> Observable.just(i.getA()).delay(Math.max(0, i.getC() - System.currentTimeMillis()),
            TimeUnit.MILLISECONDS))
        .subscribe(i -> System.out.println(i + "\t" + System.currentTimeMillis()));
    s.onNext(0);
    Thread.sleep(100);
    s.onNext(1);
    Thread.sleep(200);
    s.onNext(2);
    Thread.sleep(600);
    s.onNext(3);
    Thread.sleep(2000);
    s.onNext(4);
    Thread.sleep(200);
    s.onNext(5);
    Thread.sleep(800);
    s.onNext(6);
    Thread.sleep(1000);
  }

和输出

0   1510128693984
1   1510128694366 // 400ms
2   1510128694766 // 400ms
3   1510128695366 // 600ms
4   1510128697366 // 2000ms
5   1510128697766 // 400ms
6   1510128698567 // 800ms