如何使用Future到Future的函数映射Observable?

时间:2015-07-13 16:22:16

标签: scala rx-scala

假设我有一个类型为In的元素的事件流:

val observableIn: Observable[In] = ???

用于将In类型的对象转换为Out类型的对象,但“将来”的函数:

val futureInToFutureOut: (Future[In]) => Future[Out] = ???

此时我想根据我的函数observableIn转换futureInToFutureOut的元素。也就是说,我希望我的结果是Out类型的元素的事件流,匹配原始流的元素,但是通过函数futureInToFutureOut转换。

我认为这应该有效:

val observableOut: Observable[Out] = observableIn flatMap { in =>
  Observable.from(futureInToFutureOut(Future(in)))
}

这是对的吗?有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

编辑:

据我所知,你的解决方案是正确的。如果您想稍微提高性能,请考虑:

val observableOut: Observable[Out] = observableIn.flatMap { in =>
  val p = Promise.successful(in)
  Observable.from(futureInToFutureOut(p.future))
}

这有点快,因为它不会创建异步计算来映射未来,如Future.apply does

OLD:

我将在下面留下我的旧建议,仅适用于您在Observable中映射单个事件的情况。

import scala.concurrent._
val promiseIn = Promise[Int]()
observableIn.foreach(x => promiseIn.trySuccess(x))
val observableOut = Observable.create { observer =>
  promiseIn.future.map(futureInToFutureOut).foreach { y =>
    observer.onNext(y)
    observer.onCompleted()
  }
}

解释

由于您开始使用Observable[In]对象(即事件流),因此您需要找到一种方法将事件从Observable转移到未来。创建新未来的典型方法是先创建Promise - input side of the future object。然后,您可以在foreach上使用Observable在第一个事件到来时调用trySuccess

observableIn ---x---> foreach ---x---> promiseIn.trySuccess(x)

一旦Observable上的事件到来,承诺将异步完成。我们现在可以通过调用future方法获得承诺的阅读方面,即未来;然后在未来调用map - promiseIn.future.map(futureInToFutureOut)。图形:

promiseIn.future ---x---> map ---f(x)---> futureOut

生成的未来与futureInToFutureOut(x)异步完成。此时,我们需要找到一种通过Observable[Out]发回此值的方法。创建新Observable的典型方法是调用Observable.create工厂方法。这个方法给出了Observable的写作结束 - Observer,我们用它来调用onNext来发送事件:

futureOut ---f(x)---> foreach ---f(x)---> observer.onNext(f(x))

由于我们知道未来最多会发出一个事件,我们会在观察者上调用onCompleted来关闭输出Observable

编辑:如果您想掌握Rx和Scala期货,您可能需要考虑处理这些主题的this book。免责声明:我是作者。