所以刚接触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()
}
答案 0 :(得分:0)
您的第一个flatMapCompletable()
的结果是可完成的,因为这就是您要返回的结果。但是,该完成对象将永远不会发出值(根据定义),因此后续的flatMapCompletable()
不会映射任何值。
由于您的第一个Completable
没有发出值,因此您将需要使用andThen()
运算符或类似方法绑定下一步。
由于flatMapCompletable()
运算符的签名为Observable<Long>
,因此您的代码得以编译。您需要将andThen()
运算符放在flatMapCompletable()
函数中。