基于成功的结果失败的未来

cmb*_*ter 4 scala future

我的代码中有一个场景,我需要Future根据包含特定值的成功结果进行失败.我可以通过这项工作做得很好flatMap,但我想知道是否有更简洁的方法来完成这项工作.首先,一个非常简单的例子:

import concurrent._

case class Result(successful:Boolean)
object FutureTest {
  def main(args: Array[String]) {
    import ExecutionContext.Implicits._

    val f = Future{Result(false)}.flatMap{ result =>
      result match{
        case Result(false) => Promise.failed(new Exception("The call failed!!")).future
        case _ => Promise.successful(result).future
      }
    }

    f onFailure{
      case x => println(x.getMessage())
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

所以在我的例子中,Future如果Result返回的值为false其成功指标,我希望失败.正如我所提到的,我可以使这项工作正常flatMap,但我希望消除的代码行是:

case _ => Promise.successful(result).future
Run Code Online (Sandbox Code Playgroud)

这句话似乎没必要.我想要的行为是能够定义条件,如果它的计算结果为true,那么允许我Future像我一样返回一个不同的东西,但是如果它不是真的,那就把事情保留原样(有点像PartialFunction语义.有没有办法做到这一点,我只是没有看到?我已经看过了collect,transform而且那些看起来也不合适.

编辑

在得到map@Rex Kerr和@senia 的建议之后,我创建了PimpedFuture一个隐式转换,让代码有点像这样:

class PimpedFuture[T](f:Future[T])(implicit ex:ExecutionContext){
  def failWhen(pf:PartialFunction[T,Throwable]):Future[T] = {
    f map{
      case x if (pf.isDefinedAt(x)) => throw pf(x)
      case x => x
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

隐含的

  implicit def futToPimpedFut[T](fut:Future[T])(implicit ec:ExecutionContext):PimpedFuture[T] = new PimpedFuture(fut)
Run Code Online (Sandbox Code Playgroud)

和新的处理代码:

val f = Future{ Result(false) } failWhen {
  case Result(false) => new Exception("The call failed!!")
}
Run Code Online (Sandbox Code Playgroud)

我认为这仍然是一个更清洁,同时仍然使用建议使用map.

Rex*_*err 7

您可以通过以下方式轻松完成此操作map:

val f = Future{ Result(false) } map {
  case Result(false) => throw new Exception("The call failed!!")
  case x => x
}
Run Code Online (Sandbox Code Playgroud)

但是你仍然需要明确提到你正在传递身份.

请注意,在这种情况下不应使用andThen.andThen用于副作用,而不是用于改变结果(与Function1同名方法不同).

  • @cmbaxter:这里只有一个答案.SO是wiki资源,而不是MMORPG. (4认同)