样品不会在完成事件中停止

时间:2017-01-03 10:21:00

标签: rx-java

我正在执行第212/213页的Reactive Programming with RxJava一书中的示例:

Observable<String> names = Observable
        .just("Mary", "Patricia", "Linda", "Barbara",
                "Elizabeth", "Jennifer", "Maria", "Susan",
                "Margaret", "Dorothy");
Observable<Long> absoluteDelayMillis = Observable
        .just(0.1, 0.6, 0.9, 1.1,
                3.3, 3.4, 3.5, 3.6,
                4.4, 4.8)
        .map(d -> (long) (d * 1_000));
Observable<String> delayedNames = names
        .zipWith(absoluteDelayMillis,
                (n, d) -> Observable
                        .just(n)
                        .delay(d, TimeUnit.MILLISECONDS))
        .flatMap(o -> o);
delayedNames
        .sample(1, SECONDS)
        .subscribe(System.out::println);

当我运行代码时,输​​出为:

Linda
Barbara
Susan
Dorothy

根据这本书(以及我的想法),Dorothy不应该存在,因为sample()应该转发完成事件@ 4.8s。

我正在使用rxjava 1.1.6运行示例

我错过了什么?

3 个答案:

答案 0 :(得分:1)

这实际上是导致在2.0版本中删除了RxJava的错误。您对样本操作员的理解是正确的。

答案 1 :(得分:1)

为了澄清,这不是RxJava 1.x的错误,因为这是2016年初的requested behavior

然而,在RxJava 2.x中忽略了这一点,从2.0.4开始,它不会发出最后一个缓冲项,就像1.1.3之前的版本一样。

很遗憾,没有解决方法,但发布了enhancement PR,可以选择sample的模式。

答案 2 :(得分:-1)

Sample是一种定时器,它会在每一定时间内打勾并从“缓冲区”中选择最后一项。

在您的情况下,如果您将修改您的最后一个观察点:

long time = System.currentTimeMillis();
delayedNames
        .doOnNext(n -> System.out.println(String.format("%s - %d", n, (System.currentTimeMillis() - time))))
        .sample(1, SECONDS)
        .doOnCompleted(() -> System.out.println(String.format("complete - %d", (System.currentTimeMillis() - time))))
        .subscribe(System.out::println);

你会看到类似的输出:

Mary-155
Patricia-657
Linda-959
Linda
Barbara-1156
Barbara
Elizabeth-3355
Jennifer-3460
Maria-3558
Susan-3658
Susan
Margaret-4460
Dorothy-4856
Dorothy
complete - 4852

让我们一步一步走。

  • 首先勾选1000。正如您在输出中看到的那样,缓冲区中的最后一项是Linda
  • 第二次嘀嗒发生在2000。只有Barbara在缓冲区中。打印它。
  • 第三次蜱发生在3000。缓冲区什么都没有。
  • Forth tick发生在4000Susan是缓冲区中的最后一个。印刷。
  • 第五次嘀嗒发生在5000Dorothy是缓冲区中的最后一个。印刷。

<强> UPD:

实际上,5000上没有勾选,似乎sample将始终在缓冲区中发出最后一项。例如,如果您将修改源可观察量:

    Observable<String> names = Observable
            .just("Mary", "Patricia", "Linda", "Barbara",
                    "Elizabeth", "Jennifer", "Maria", "Susan");
    Observable<Long> absoluteDelayMillis = Observable.just(0.1, 0.6, 0.9, 1.1, 3.3, 3.4, 3.5, 3.6)

它将打印:

Mary - 153
Patricia - 654
Linda - 957
Linda
Barbara - 1157
Barbara
Elizabeth - 3358
Jennifer - 3457
Maria - 3559
Susan - 3658
Susan
complete - 3659

<强> UPD2:

我创建了bug report

<强> UPD3:

我已经检查过并且在rxjava2中它按预期工作。