中断 Future map chain 和 return a Left

Interrupt Future map chain and return a Left

我怎样才能 return a Left 在未来地图链的中间,然后使未来失败?我正在发送一个例子来澄清。

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

object TestApp extends App {

  final case class Message(statusCode: Int, data: String)
  final case class Success(data: String)
  final case class Failure()

  val msg = Message(500, "My data")
  val future = Future { msg }

  def getMessage(future: Future[Message]): Future[Either[Failure, Success]] = {
    future.map { msg =>
      // Evaluate msg here - if failure, make this feature fail and then return Left(Failure), otherwise, continue in the chain
      msg
    }.map(_.data).map(data => Right(Success(data)))
  }
}

一个选项是抛出一个异常,这将使 Future 失败,然后 recoverLeft,就像这样

  def getMessage(future: Future[Message]): Future[Either[Failure, Success]] =
    future
      .map(msg => if (msg.statusCode == 500) throw new RuntimeException("boom") else msg)
      .map(_.data)
      .map(data => Right(Success(data)))
      .recover{case ex => Left(Failure())}

另一种选择是transform像这样

  def getMessage(future: Future[Message]): Future[Either[Failure, Success]] = {
    future
      .map(msg => if (msg.statusCode == 500) throw new RuntimeException("boom") else msg)
      .map(_.data)
      .transform(v => scala.util.Success {
        v.toEither
          .map(v => Success(v))
          .left.map(e => Failure())
      })
  }

警告,您已经定义了自己的 Success/Failure,它隐藏了 Scala 的 Success/Failure