可观察vs可完成为什么不调用可完成任务?

时间:2018-06-26 14:39:36

标签: java rx-java

所以刚接触RX Java的人有一个问题。

在我的探险动物RXJava的探险中,这是我的课程。

public class PollingLoop {

public static <T> Observable<T> buildObservable(
    final int interval,
    final TimeUnit timeUnit,
    final int maxJitter,
    final Scheduler scheduler,
    final Supplier<Observable<T>> scheduledTask) {

    if (maxJitter <= 0) throw new IllegalArgumentException("Jitter must be greater than 0");

    final Random randomJitter = new Random();
    return Observable.timer(interval, timeUnit, scheduler)
        .map(x -> {
            System.out.println("Flat map jitter");
            return randomJitter.nextInt(maxJitter);
        })
        .flatMap(jitter -> {
            System.out.println("Flat map timer");
            return Observable.timer(jitter, timeUnit, scheduler);
        })
        .flatMap(ignored -> {
            System.out.println("Flat map task");
            return scheduledTask.get();
        })
        .retry()
        .repeat();
}

public static <T> Completable buildCompletable(
    final int interval,
    final TimeUnit timeUnit,
    final int maxJitter,
    final Scheduler scheduler,
    final Supplier<Completable> scheduledTask) {

    if (maxJitter <= 0) throw new IllegalArgumentException("Jitter must be greater than 0");

    final Random randomJitter = new Random();
    return Observable.timer(interval, timeUnit, scheduler)
        .map(x -> {
            System.out.println("Flat map jitter");
            return randomJitter.nextInt(maxJitter);
        })
        .flatMapCompletable(jitter -> {
            System.out.println("Flat map timer");
            return Completable.timer(jitter, timeUnit, scheduler);
        })
        .flatMapCompletable(ignored -> {
            System.out.println("Flat map task that is not called");
            return scheduledTask.get();
        })
        .retry()
        .repeat()
        .toCompletable();
}
}

从测试中,当我测试Observable的执行延迟时,我得到输出

Flat map jitter
Flat map timer
Flat map task //(observable is being called)

但是当我测试Completable的执行延迟时,我会得到输出

Flat map jitter
Flat map timer

//(未调用完成的任务)

我在做什么错?为什么未从buildCompletable内部调用Completable任务?

这是测试(用spock编写)

def 'should delay execution of observable'() {
    given:
    def subscriber = new TestSubscriber<>()
    def scheduler = new TestScheduler()
    def supplier = Mock Supplier

    supplier.get() >> Observable.just(true)

    when:
    PollingLoop.buildObservable(100, TimeUnit.MILLISECONDS, 1, scheduler, supplier).subscribe(subscriber)
    scheduler.advanceTimeBy(101, TimeUnit.MILLISECONDS)

    then:
    subscriber.assertValueCount(1)
    subscriber.assertValue(true)
}

    def 'should delay execution of completable'(){
    given:
    def subscriber = new TestSubscriber<>()
    def scheduler = new TestScheduler()
    def supplier = Mock Supplier
    supplier.get() >> Completable.complete()

    when:
    PollingLoop.buildCompletable(100, TimeUnit.MILLISECONDS, 1, scheduler, supplier).subscribe(subscriber)

    scheduler.advanceTimeBy(1001, TimeUnit.MILLISECONDS)
enter code here
    then:
    1 * supplier.get()
}

1 个答案:

答案 0 :(得分:0)

您的第一个flatMapCompletable()的结果是可完成的,因为这就是您要返回的结果。但是,该完成对象将永远不会发出值(根据定义),因此后续的flatMapCompletable()不会映射任何值。

由于您的第一个Completable没有发出值,因此您将需要使用andThen()运算符或类似方法绑定下一步。

由于flatMapCompletable()运算符的签名为Observable<Long>,因此您的代码得以编译。您需要将andThen()运算符放在flatMapCompletable()函数中。