我正在使用 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
然后在 中履行该 promise >onComplete()
回调。为了处理提供的标题没有文档的情况,我别无选择,只能声明这个 var empty: Boolean = true
变量,然后在 onNext()
和onComplete()
回调。
问题:在我的 Observer
实例中不使用 var
有没有更好的方法来解决这个问题?
最佳答案
我认为使用 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)
}
future 的T
其实就是一个Seq[T]
。这样一个简单的检查就可以消除对可变状态的需要。
关于MongoDB Scala 驱动程序 : what is a best way to return Future when working with Observer callbacks?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38415762/