我正在使用Scala驱动程序在Play Framework和MongoDB上编写一个简单的博客。 所以它有效,我很高兴,但感觉我的代码不够好。 你们可以回顾下面的片段,这是我的mongo服务方法之一,并告诉我是否有办法让它更干净:
def findByTitle(title:String)(implicit ec:ExecutionContext):Future[Option[Document]] = {
val collection = db.getCollection("items")
val results = collection.find(equal("title", title))
val contentPromise: Promise[Option[Document]] = Promise()
results.subscribe(new Observer[scala.Document] {
var empty: Boolean = true
override def onError(e: Throwable): Unit = println("Error")
override def onComplete(): Unit = {
if (empty) contentPromise.success(None)
}
override def onNext(result: scala.Document): Unit = {
empty = false
contentPromise.success(Some(result))
}
})
contentPromise.future
}
我决定返回Future[Option[Document]]
因为提供的标题可能没有任何内容。至于使用Observable
的唯一方法是通过Observer
回调,我需要声明Promise
,然后在onComplete()
回调中履行该承诺。为了处理没有提供标题的文档的情况,我除了声明这个var empty: Boolean = true
变量,然后在onNext()
和onComplete()
回调中使用它外别无选择。
问题:如果不在我的var
实例中使用Observer
,是否有更好的方法来解决此问题?
答案 0 :(得分:15)
我认为使用Future[T]
代替可观察对象要容易得多:
import org.mongodb.scala.ObservableImplicits._
def findByTitle(title: String)(implicit ec: ExecutionContext): Future[Option[Document]] = {
val collection = db.getCollection("it")
collection.find(equal("title", title))
.toFuture()
.recoverWith { case e: Throwable => { Log(e); Future.failed(e) } }
.map(_.headOption)
}
将来T
实际上是Seq[T]
。这样一个简单的检查可以消除对可变状态的需要。