如何从样本数组创建Observable?

时间:2015-11-12 14:28:54

标签: java rx-java observable

假设我们从传感器读取了一些样本缓冲区。每次我在其上运行一个方法(即buffer.fetchNewSamples())时,缓冲区都会被提供新的样本。如何从这样的对象创建Java Rx Observable,它将逐个从缓冲区返回每个样本,并在发出最后一个样本时调用buffer.fetchNewSamples(),然后以相同的方式继续?

我刚刚开始使用Rx,虽然很容易创建一个返回的observable,即这种缓冲区的平均值,但我不知道如何在不创建新线程的情况下创建上述内容并进行一些同步...

1 个答案:

答案 0 :(得分:2)

给定一个感官API float[] measure(),您可以按以下顺序进行定时测量和发射:

Observable.interval(10, TimeUnit.MILLISECONDS)
    .onBackpressureDrop()
    .map(t -> measure())
    .concatMap(fa -> Observable.range(0, fa.length).map(i -> fa[i]))
.subscribe(...)

<强>解释

给定10ms的间隔,丢弃任何未请求的内容,并将计时器值映射到测量值的数组(这种情况每10ms发生一次)。给定测量数组,一个接一个地发射,通过相当于索引的for循环将其展平到其数组元素,但确保下一个测量值仅在前一个完成发射数组元素之后才出现。最后,你有一个漂浮物流。

如果您希望在消耗完前一次通话的所有测量后立即测量,则可以执行以下操作:

BehaviorSubject<Integer> bs = BehaviorSubject.create(1);

bs.observeOn(Schedulers.trampoline())
.map(t -> measure())
.concatMap(fa -> 
    Observable.range(0, fa.length).map(i -> fa[i])
    .finallyDo(() -> bs.onNext(1))
)

<强>解释 我们利用BehaviorSubject的行为将其存储的值发送给第一个订户,我们将使用它来触发测量。为了避免无限递归,我们将在trampoline调度程序上观察主题。一旦信号通过,我们进行测量并将其转换为如上所述的一系列浮点数。唯一的区别是,只要这样的子序列完成,它就会发信号通知BehaviorSubject触发另一个测量。