Scala隔离了某些flatmap

时间:2018-03-07 18:56:07

标签: scala playframework reactive-programming dry

我在约20个地方使用了flatMap。我相信将来还会再增加20个。当Option为空时抛出异常。

示例:

def get(serverId: UUID, sessionId: UUID) = authAction.async { implicit request =>
  val user = request.user.get
  serverService.findByIdAndUserId(serverId, user.id.get) flatMap { s =>
    if (s.isEmpty) {
      Future.failed(new NotFoundException)
    } else {
      Future.successful(s.get)
    }
  } flatMap { _ =>
    serverSessionService.findByIdAndServerId(sessionId, serverId)
  } flatMap { s =>
    if (s.isEmpty) {
      Future.failed(new NotFoundException)
    } else {
      Future.successful(s.get)
    }
  } map { s =>
    Ok(Json.toJson(s))
  }
}

我在一个控制器方法中执行flatMap Option两次检查......

我如何隔离这部分:

flatMap { s =>
  if (s.isEmpty) {
    Future.failed(new NotFoundException)
  } else {
    Future.successful(s.get)
  }
}

2 个答案:

答案 0 :(得分:0)

如果为空,我建议添加隐式类失败:

implicit class FutureFailer[T <: Option[_]](f: Future[T]) {
    def failIfEmpty = {
        f.flatMap {
            case None => Future.failed(new NotFoundException)
            case k => Future.successful(k)
        }
    }
}

Future.successful(Option.empty[String]).failIfEmpty.
    flatMap(_ => Future.successful(Option.empty[String])).failIfEmpty

答案 1 :(得分:0)

这是一种使用隐式类的方法:

implicit class OptionFuture[T](f: Future[Option[T]]) {
  def optionFuture(t: Throwable): Future[T] =
    f.flatMap{
      case Some(x) => Future.successful(x)
      case _ => Future.failed(t)
    }
}

Future{ Some(1) }.optionFuture(new Exception("failed"))
// Success(1)

Future{ None }.optionFuture(new Exception("failed"))
// Failure(java.lang.Exception: failed)