【问题标题】:Interrupt Future map chain and return a Left中断 Future 映射链并返回一个 Left
【发布时间】:2020-04-26 04:41:43
【问题描述】:

如何在未来的地图链中间返回一个 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)))
  }
}

【问题讨论】:

    标签: scala future either


    【解决方案1】:

    一种选择是抛出一个异常,该异常将使Future 失败,然后recover 失败为Left,就像这样

      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

    【讨论】:

      猜你喜欢
      • 2013-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 1970-01-01
      • 1970-01-01
      • 2020-07-04
      相关资源
      最近更新 更多