假设有一个高速公路入口和一个停车标志。
以下是规则:
1,第一辆无需任何等待即刻进入高速公路的汽车。 2,在任何其他时间,其他汽车必须在前一辆汽车通过后至少等待2.5秒。 3,请注意,这并不意味着所有汽车都必须等待2.5秒。 例如,第一辆汽车立即通过。 10小时后,这是第二辆车。它应该立即通过,因为第一辆车已经过了10个小时,而这是很久以前的事了。 要求第二辆汽车等待2.5秒没有任何意义。但是,假设第二辆车出现后,第三辆车的显示时间为1200毫秒,这瞬间过去了。第三辆车需要等待1300毫秒。
我在github repo中有使用单元测试的代码,并且单元测试通过了。但是我真的不喜欢引入副作用的事实。
private int passedCarCount;
private int timeSpanCount;
因此,我正在编写此示例应用程序,希望让Rx专家优化代码。高度赞赏的是,如果我们能够以一种干净的方式完成它。
package com.tonytangandroid.rxjava_stop_sign.demo;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.Scheduler;
public class ThrottleCarStream {
private final CarStream carStream;
private final Scheduler scheduler;
private int passedCarCount;
private int timeSpanCount;
public ThrottleCarStream(CarStream carStream, Scheduler scheduler) {
this.carStream = carStream;
this.scheduler = scheduler;
}
public Observable<Car> periodUserActionStream() {
return zip();
}
private Observable<Car> zip() {
return Observable.zip(rawStream(), internal(), this::value);
}
private Observable<Long> internal() {
return Observable.interval(0, 2500, TimeUnit.MILLISECONDS, scheduler)
.doOnSubscribe(disposable -> initSpanCount())
.filter(c -> whenCarCountGreaterOrEqualThanTimeSpanCount())
.doOnNext(aLong -> increaseSpanCount());
}
private boolean whenCarCountGreaterOrEqualThanTimeSpanCount() {
return passedCarCount >= timeSpanCount;
}
private void increaseSpanCount() {
timeSpanCount++;
}
private void initSpanCount() {
timeSpanCount = 0;
}
private Car value(Car cmdMessage, Long time) {
return cmdMessage;
}
private Observable<Car> rawStream() {
return carStream.cmdStream()
.doOnSubscribe(disposable -> initElementCount())
.doOnNext(cmdMessage -> increaseElementCount());
}
private void increaseElementCount() {
passedCarCount++;
}
private void initElementCount() {
passedCarCount = 0;
}
}
答案 0 :(得分:0)
这应该有效:
@RequiredArgsConstructor
public class DelayTransformer<T> implements ObservableTransformer<T, T> {
private Long last = null;
final long limit;
@Override
public ObservableSource<T> apply(final Observable<T> upstream) {
return upstream.flatMap(x -> {
final long current = System.currentTimeMillis();
final long delay = last == null ?
0 : Math.max(0, limit - (current - last));
last = current + delay;
return Observable.just(x).delay(delay, TimeUnit.MILLISECONDS);
});
}
}
// Caller
Observable<String> car1 = Observable
.just("car1")
.delay(100, TimeUnit.MILLISECONDS);
Observable<String> car2 = Observable
.just("car2")
.delay(200, TimeUnit.MILLISECONDS);
Observable<String> car3 = Observable
.just("car3")
.delay(2500, TimeUnit.MILLISECONDS);
Observable<String> cars = Observable
.merge(car1, car2, car3);
cars
.doOnNext(x -> log.info("Received: {}", x))
.compose(new DelayTransformer<>(1500))
.blockingSubscribe(x -> log.info("Emitted: {}", x));
我有以下输出:
[INFO ] 2019-12-28 01:11:06.107 [RxComputationThreadPool-1] App - Received: car1
[INFO ] 2019-12-28 01:11:06.128 [main] App - Emitted: car1
[INFO ] 2019-12-28 01:11:06.189 [RxComputationThreadPool-2] App - Received: car2
[INFO ] 2019-12-28 01:11:07.622 [main] App - Emitted: car2
[INFO ] 2019-12-28 01:11:08.490 [RxComputationThreadPool-3] App - Received: car3
[INFO ] 2019-12-28 01:11:09.122 [main] App - Emitted: car3