Scala 期货理解中的期权处理

Scala 期货理解中的期权处理,scala,playframework,future,optional,playframework-2.3,Scala,Playframework,Future,Optional,Playframework 2.3,考虑Play Framework控制器中的以下代码: val firstFuture = function1(id) val secondFuture = function2(id) val resultFuture = for { first <- firstFuture second <- secondFuture(_.get) result <- function3(first, second) } yield Ok(s"Processed $id") res

考虑Play Framework控制器中的以下代码:

val firstFuture = function1(id)
val secondFuture = function2(id)
val resultFuture = for {
  first <- firstFuture
  second <- secondFuture(_.get)
  result <- function3(first, second)
} yield Ok(s"Processed $id")
resultFuture.map(result => result).recover { case t => InternalServerError(s"Error organizing files: $t.getMessage")}
val firstFuture=function1(id)
val secondFuture=function2(id)
val resultFuture=for{

首先可能使用
collect
,然后您可以
恢复
NoSuchElementException
——是的,它将从任何步骤中恢复失败。
resultFuture
将在映射的
结果中成功,或者在抛出的第一个异常中失败

val firstFuture = function1(id)
val secondFuture = function2(id)
val resultFuture = for {
   first <- firstFuture
   second <- secondFuture.collect(case Some(x) => x)
   result <- function3(first, second)
} yield Ok(s"Processed $id")

resultFuture.map(result => result)
   .recover { case java.util.NoSuchElementException => NotFound } 
   .recover { case t => InternalServerError(s"Error organizing files: $t.getMessage")}
val firstFuture=function1(id)
val secondFuture=function2(id)
val resultFuture=for{
首次未找到}
.recover{case t=>InternalServerError(s“组织文件时出错:$t.getMessage”)}

我会选择Scalaz OptionT。也许将来只有一个函数[Optipn[T]]会有些过分,但当你开始添加更多函数时,它会变得非常有用

  import scala.concurrent.ExecutionContext.Implicits.global
  import scalaz.OptionT
  import scalaz.OptionT._
  import scalaz.std.scalaFuture._

  // Wrap 'some' result into OptionT
  private def someOptionT[T](t: Future[T]): OptionT[Future, T] = 
    optionT[Future](t.map(Some.apply))

  val firstFuture = function1(id)
  val secondFuture = function2(id)

  val action = for {
    list <- someOptionT(firstFuture)
    person <- optionT(secondFuture)
    result = function3(list, person)
  } yield result

  action.run.map {
    case None => NotFound
    case Some(result) => Ok(s"Processed $id")
  } recover {
    case NonFatal(err) => InternalServerError(s"Error organizing files: ${err.getMessage}")
  }
导入scala.concurrent.ExecutionContext.Implicits.global
进口scalaz.option
导入scalaz.option_
导入scalaz.std.scalaFuture_
//将“某些”结果包装到OptionT中
私有def someOptionT[T](T:Future[T]):OptionT[Future,T]=
optionT[未来](t.map(部分应用))
val firstFuture=function1(id)
val secondFuture=function2(id)
val操作=用于{
列表确定(s“已处理$id”)
}恢复{
case NonFatal(err)=>InternalServerError(s“组织文件时出错:${err.getMessage}”)
}

现在我想起来了,使用
collect
.map(uu.get)
没有什么不同,在这种情况下,因为两者都会导致恢复相同的异常。也考虑过这种方法,但感觉有点恶心(非惯用)为
None
案例生成异常只是为了稍后捕获它。这可能是最简单的方法。我有点担心为这个案例添加另一个依赖项,但您可能是对的,Scalaz将在更类似的情况下获得回报。它有许多有用的抽象,可以节省您大量的时间,并使代码更具吸引力小一些,我建议你开始使用,这样你的解决方案在经过一些调整后对我有效。但我不知道为什么哈哈。如果你有时间,你能提供关于
optionT
方法的详细信息吗?以及
someOptionT
方法的必要性吗?我建议你开始使用。使用optionT Future应该是Option[T],但firstFuture只是Future[T],基本上可以用optionT(firstFuture.map(result=>Option(result))替换它)