代码之家  ›  专栏  ›  技术社区  ›  Niko

Scala Future:将Future[Vector[T]]转换为Future[Result]

  •  0
  • Niko  · 技术社区  · 5 年前

    我有一个方法可以创建一个 Future 类型 Vector

    到目前为止,我已经尝试使用 transform transformWith Try[T] 签名为他们的论点,我可以区分成功和失败。

    未来 类型 矢量

    def aCoupleOfFutures: Future[Vector[String]] = ???
    

    Try 结构

    val foo:Future[Result] = aCoupleOfFutures.transform {
        case Success(strings) => Try(Created(json.Json.toJson(strings)))
        case Failure(e) => Try(BadRequest(e.getMessage))
    }
    

    Future.successful 筑巢。

    val foo:Future[Result] = aCoupleOfFutures.transformWith {
        case Success(strings) => Future.successful(Created(json.Json.toJson(strings)))
        case Failure(e) => Future.successful(BadRequest(e.getMessage))
    }
    

    BadRequest 当服务产生异常时。因为这个人的签名 转型 def transform[S](s: T => S, f: Throwable => Throwable) )

    val foo:Future[Result] = aCoupleOfFutures.transform (
        options => Created(json.Json.toJson(options)),
        exc => exc
    )
    

    所以我的问题是:我能有如下的东西吗

    val result:Future[Result] = aCoupleOfFutures. someKindOfTransform {
        case Success(options) => Created(json.Json.toJson(options))
        case Failure(e) => BadRequest(e.getMessage)
    }
    
    0 回复  |  直到 5 年前
        1
  •  2
  •   Astrid    5 年前

    最简单的选择似乎是把它分成几个部分 map recover 步骤:

    val result = aCoupleOfFutures
      .map(options => Created(json.Json.toJson(options)))
      .recover{ case exc => BadRequest(exc.getMessage)}
    

    你是对的,似乎没有一个单一的转换方法做你想要的-最接近的签名似乎是 onComplete ,但那又回来了 Unit 所以不允许你产生一个返回值。也就是说,将两者分开并不一定是件坏事,因为您通常希望在所有控制器中抽象出错误处理逻辑。

        2
  •  1
  •   Gagandeep Kalra    5 年前

    折叠操作在这里很有用-

    def fold[U](fa: Throwable => U, fb: T => U): U
    

    Result . 对try/other/option的折叠操作会将处于任何状态的整个对象转换为一个类型 U

    val result = aCoupleOfFutures
      .transform(
        tryResult =>
          Success(
            tryResult.fold(th => BadRequest(th.getMessage), options => Created(json.Json.toJson(options)))
          )
      )