Scala Future未输入onComplete()

时间:2017-03-10 19:12:46

标签: scala functional-programming future

我正在尝试从导致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) => {

        }
})

2 个答案:

答案 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.但是,添加一个简单的AwaitThreed.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.
      }
}