Scala Observable Creation阻止了我的未来

时间:2015-11-18 06:35:26

标签: scala concurrency parallel-processing functional-programming rx-scala

我想要处理ea。查询提取(可能是每个查询多次提取)异步。为了做到这一点,我将处理函数(返回Future)传递给我的查询方法,以便将其调用为ea。取。我事先并不知道查询的结果大小;我只知道我的抓取的最大尺寸。因此,我的查询返回Observable(而不是前面的List,我需要事先知道大小)。唯一的问题是,当我使用Observable createapply时,它会在内部阻止,直到我的Future完成后再调用下一个onNext - 有效地删除了我希望从期货中获得业绩增长。 Observable from工厂方法不会阻止,但需要Iterable。我可以传递一个可变的Iterable并随着新的进入而增长。有人有一个更具参考性的透明溶胶吗?这是代码:

object Repository {
  def query(fetchSize: Int)(f: Set[Int] => Future[Set[Int]]): Observable[Future[Set[Int]]] = {
    // observable (as opposed to list) because modeling a process 
    // where the total result size is unknown beforehand. 
    // Also, not creating or applying because it blocks the futures
    val mut = scala.collection.mutable.Set[Future[Set[Int]]]()
    val obs = Observable.from(mut)
    1 to 2100 by fetchSize foreach { i =>
      mut += f(DataSource.fetch(i, fetchSize))
    }
    obs
  }
}

1 个答案:

答案 0 :(得分:0)

我能够通过使用foldLeft:

来消除可变性
(1 to 21 by fetchSize).foldLeft(Observable just Future((Set[Int]()))) { (obs, i) =>
  obs + f(DataSource.fetch(i)())
}

其中:

implicit class FutureObservable(obs: Observable[Future[Set[Int]]]) {
  def +(future: Future[Set[Int]]) =
  obs merge (Observable just future)
}

唯一的问题是我不喜欢我必须做的事情,创建一个编译器没有抱怨的空Observable。如果有人有更好的答案,请发一个,我会标记。