热观察消耗不同的频率

时间:2017-11-03 14:37:46

标签: scala concurrency observable monix

我正在为我正在尝试完成的任务开发一个简单的示例。 假设有一个任务列表(tasks)我想每1秒触发

可以使用scheduler或其他任何方式完成。

现在此流的消费者有两个,

  • C1应在完成所有任务时触发
  • C2应在每次完成所有任务时触发。 (也可以每隔n秒)

以下是一些示例代码。目前,它没有安排重复 - 因为我不知道使用Observable.repeat还是Scheduler是否更好。

import monix.eval.Task
import monix.execution.Scheduler.Implicits.global
import monix.execution.Scheduler.{global => scheduler}
import monix.reactive.{Consumer, Observable}

import scala.concurrent.duration._

object MainTest {

  def main(args: Array[String]): Unit = {

    def t = (i: Int) => Observable.eval {
      print(i)
      i
    }

    val tsks = (1 to 5).map(t)

    val tasks = Observable.fromIterable(tsks).flatten.doOnCompleteEval(Task.eval(println("")))

    val c1 = Consumer.foreach[Int](x => println(s"C1: [$x]"))
    val c2 = Consumer.foreach[Int](x => println(s"C2: [$x]"))

    val s = tasks.reduce(_ + _).publish

    s.consumeWith(c1).runAsync
    s.consumeWith(c2).runAsync
    s.connect()

    while (true) {
      Thread.sleep(1.hour.toMillis)
    }
  }

}

1 个答案:

答案 0 :(得分:2)

首先,为了每1秒重复一次任务,你可以做......

Observable.intervalAtFixedRate(1.second)
  .flatMap(_ => Observable.eval(???))

要在完成所有任务时触发,您可以使用completed(如果您想要Observable[Nothing]仅发出最终完成事件)或completedL(如果您想要工作)改为使用Task[Unit]。 有关详细信息,请参阅API docs

因此,您可以执行以下操作,而不是c1

s.completeL.runAsync

然而,对于来源采样,您可以使用:

  • sample(别名throttleLast
  • sampleRepeated
  • throttleFirst
  • debounce
  • debounceRepeated
  • echo
  • echoRepeated

我鼓励您玩这些,从API docs开始。

s.sample(10.seconds).doOnNext(println).completedL.runAsync

或者您可以使用takeEveryNth

简单地获取每个第N个元素
s.takeEveryNth(20).doOnNext(println).completedL.runAsync

如果这回答了你的问题,请告诉我。