MongoDB scala驱动程序:使用Observer回调时返回Future的最佳方法是什么?

Ale*_*dar 10 scala mongodb playframework

我正在使用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
  }
Run Code Online (Sandbox Code Playgroud)

我决定回来,Future[Option[Document]]因为有可能没有提供标题.只要使用的唯一方法Observable是通过Observer回调,我需要声明a Promise然后在onComplete()回调中履行该承诺.为了处理这种情况时,有提供名称,没有文件我有比这个声明没有其他选择var empty: Boolean = true的变量,然后用它onNext()onComplete()回调.

问题:如果不在var我的Observer实例中使用,有没有更好的方法来解决这个问题?

Yuv*_*kov 16

我认为使用a Future[T]而不是observable 更容易:

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)
}
Run Code Online (Sandbox Code Playgroud)

T在未来实际上是一个Seq[T].这样一个简单的检查可以消除对可变状态的需要.