我有一组与interval
一起使用的项目,如下所示:
Observable.just(1, 2, 3, 4)
.zipWith(Observable.interval(3500, TimeUnit.MILLISECONDS), (item, interval) -> item)
.subscribe()
当前流程是每个项目显示3500毫秒。我想实现的是,如果用户在达到3500ms之前点击按钮,则跳到下一个项目。
我试图通过Subject
实现这一点,但没有成功。
也许,您可以使用amb()
将计时器与用户单击结合起来。amb()
将发出计时器滴答声或用户点击声,具体取决于最先触发的是哪一个。然后,您可以使用repeat()
来获得重复执行。下面,用户点击是";模拟的";而计时器已设置为5秒(而不是检查样本的3500毫秒(:
public static void main(String[] args) {
final Random random = new Random();
final Observable<String> userClick =
Observable.defer(() -> Observable.just(random.nextInt(8)))
.flatMap(t -> Observable.timer(t, SECONDS).map(__ -> (long) t))
.map(t -> String.format("user click after %d seconds", t));
final Observable<String> timer = Observable.timer(5, SECONDS)
.map(__ -> "tick after 5 seconds!");
Observable.just(1, 2, 3, 4, 5)
.zipWith(Observable.ambArray(timer, userClick)
.doOnNext(s -> System.out.printf("%sn", s))
.repeat(),
(item, tick) -> item)
.subscribe(System.out::println,
System.err::println,
() -> System.out.println("End!"));
Flowable.timer(1, MINUTES) // Just to block the main thread for a while
.blockingSubscribe();
}
如果你运行这个程序,你可以得到这样的结果:
tick after 5 seconds!
1
user click after 3 seconds
2
tick after 5 seconds!
3
user click after 0 seconds
4
user click after 1 seconds
5
End!
以下是对我有效的操作(takeUntil
运算符条件(:
Observable.just(1, 2, 3, 4)
.zipWith(
intervalRange()
.doOnNext {
onEachIntervalEmit(it)
}
.takeUntil(buttonUneStream)
.takeUntil(buttonUnStream)
.repeat()
intervalRang
定义的一些细节:
private fun intervalRange(): Flowable<Long> {
return Flowable.intervalRange(
0,
10,
0,
4,
TimeUnit.SECONDS,
AndroidSchedulers.mainThread()
)
}
我非常喜欢intervalRange
,因为它允许指定初始延迟。