假设我有一个类型为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)))
}
这是对的吗?有更好的方法吗?
答案 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。免责声明:我是作者。