Scala 隔离某些平面图

Scala isolate certain flatmap

我在大约 20 个地方使用了某种 flatMap。我相信将来还会有 20 个。就是当aOption为空时抛异常。

示例:

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))
  }
}

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

如何隔离这部分:

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

我建议添加隐式 class 以在空时失败:

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

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

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)