我正在尝试从导致Future
的代码片段中获取值,但是当我浏览代码时,事实证明它从未进入onComplete
函数。有什么我做错了吗?
我也试过使用地图,因为在其他帖子中有人建议,但没有成功
override def findOrCreate(phoneNumber: String, creationReason: String): Future[AvroCustomer] = {
//query for customer in db
val avroCustomer: Future[AvroCustomer] = customerByPhone(phoneNumber)
avroCustomer.onComplete({
case Success(null) => {
createUserAndEvent(phoneNumber, creationReason, 1.0)
}
case Success(customer) => {
Future.successful(customer)
}
case Failure(exception) => {
}
})
答案 0 :(得分:2)
回答扩展评论。这个虚拟程序不会打印任何内容。
import scala.concurrent.Future
import scala.util.{Failure, Success}
import scala.concurrent.ExecutionContext.Implicits.global
object Quickie {
def main(args: Array[String]): Unit = {
val addOneInFuture: Future[Int] = Future(addOne(3))
addOneInFuture.onComplete {
case Success(s) => println(s)
case Failure(ex) => println(ex.toString)
case _ => println("what the hell happened")
}
}
def addOne(x: Int): Int = x + 1
}
我启动了一个新线程,但由于该值永远不需要,我将看不到打印的4.但是,添加一个简单的Await
,Threed.sleep(_eternity_)
,甚至是另一个println
和你会看到结果。在Scala中了解Futures
的一件事是你想要将它们组合并作为集合处理(因此它们只有for-comprehensions
)并且你很少想要做某事并打印。如果你做了一些数据库或休息IO,你仍然会进一步处理数据。
丹尼尔·威斯特海德(Daniel Westheide)有一篇古老而又金色的博客系列,你可以阅读。 http://danielwestheide.com/blog/2013/01/09/the-neophytes-guide-to-scala-part-8-welcome-to-the-future.html
答案 1 :(得分:1)
Imo,而不是使用OnComplete,它不会返回你想要的东西(OnComplete是一种Unit
类型的方法),首先,你可以尝试在数据库端捕获异常,或者使用Try类型或者恢复,然后让你的方法返回Option[AvroCustomer]
。
这是scala的完美用例可选包装器类型(使用null类型的Scala-tastic方法)。如果customerByPhone因任何原因返回null,您可以在db函数端捕获它并将其转换为可选类型。
,即非如此,如果它是可以为空的类型:
def customerByPhone(s: String) = {
... //Some code
db.run(query).map(Option(_))
}
现在生成一个Option[avroCustomer]
,然后您可以这样链接:
override def findOrCreate(phoneNumber: String, creationReason: String): Future[AvroCustomer] = {
//query for customer in db
customerByPhone(phoneNumber).flatMap {
case Some(customer) => Future.successful(customer)
case None => createUserAndEvent(phoneNumber, creationReason, 1.0) //I'm assuming this returns a futures.
}
}