我们已经花费了相当多的笔墨来研究可以自己创建线程的Observable,这在RxJava中不是最好的模式。在后面的章节中,我们将探讨调度器,但首先我们将发现两个非常有用的操作符,它们使用下面的线程:timer()和interval()。前者只是创建了一个Observable ,它在指定的延迟之后发出一个值为0的值,然后完成:
Observable
.timer(1, TimeUnit.SECONDS)
.subscribe((Long zero) -> log(zero));
虽然听起来很傻,但timer()非常有用。它基本上是一个异步的Thread.sleep()。我们不是阻塞当前线程,而是创建一个Observable 并subscribe()订阅到它。在我们学习如何将简单的Observable 合成为更复杂的计算之后,它将变得更加重要。固定值0(就是变量zero)只是一个没有特定含义的约定。然而,当interval()被引入时,它更有意义。interval()生成一个long序列,从0开始,每个值之间有一个固定的延迟:
Observable
.interval(1_000_000 / 60, MICROSECONDS)
.subscribe((Long i) -> log(i));
译者注:time()即在一定延迟之后,发送0L,而interval()就是以规定的延迟为循环,从0L开始发射递增数字。
Observable.interval()产生一系列连续的长数字,从0开始。然而,与range()不同,interval()在每个事件之前都放置一个固定的延迟,包括第一个事件。在我们的例子中,这种延迟大约是16666μs,大致对应于60 Hz,帧速率通常用于各种动画。这不是一个巧合:interval()有时用于控制需要以特定频率运行的动画或进程。interval()与ScheduledExecutorService的scheduleAtFixedRate()有点类似。你可以想象出该方法的多种用法,比如数据的周期性轮询、刷新的用户界面,或者模拟的运行时间。