繁体   English   中英

使用 Cats 从 Future 中提取价值

[英]Extract value from Future using Cats

我正在尝试为 GitHub 的 API 编写一个小型库。 我正在尝试模拟Github4s 库的行为,这里是这个库的一个例子:

val user1 = Github(accessToken).users.get("rafaparadela")
object ProgramEval {
    val u1 = user1.exec[Eval, HttpResponse[String]]().value
 }

import cats.implicits._
import github4s.GithubResponses.GHResult

ProgramEval.u1 match {
  // Here the actual value of the request is returned, 
  // not the same as Future's onComplete, where the return type is Unit
  case Right(GHResult(result, status, headers)) => result.login
  case Left(e) => e.getMessage
}

我引用文档:

每个 Github4s API 调用都会返回一个 GHIO[GHResponse[A]],它是 Free[Github4s, GHResponse[A]] 的别名。

GHResponse[A] 又是 Either[GHException, GHResult[A]] 的类型别名。

GHResult 包含 Github 给出的结果 A 以及响应的状态码和标头:

在某些时候,他们正在使用HttpClient.scala发出HttpRequest

我怎么能自己复制这种行为? 我曾尝试像示例中那样使用 Cats.Eval ,但最终得到了相同的Future[String]

此外,我在提出请求时面临一些嵌套问题,例如,要获取组织的贡献者列表,我需要提出两个HttpRequest

  • 一种用于获取组织回购
  • 每个 repo 一个,以获得贡献者列表

这个结果在Future[List[Future[Users]]]上,我面临与上面相同的问题,为了获得结果,我必须这样做:

(result:Future[List[Future[Users]]]) onComplete { users =>
    users.foreach {
        _  onComplete {
            // Process result
        }
    }
}

但我想将值返回为github4s 我一直在阅读有关Cats 的 Applicative 和 Traversable Functors 的文章,但运气不佳。

您可以使用Future.sequenceList[Future]转换为Future[List] ,然后压缩嵌套的期货。

结果代码:

val input: Future[List[Future[Users]]] = ???
implicit  val ec: ExecutionContext = ExecutionContext.global
val result: Future[List[Users]] = input.flatMap(list => Future.sequence(list))

不知道为什么你认为这个问题会被猫解决。 看来您最终想要的是String (正文值),而不是Future[String]

从 Future 中提取值的唯一方法是使用Await阻止主线程等待它。 由于这不是很有效,您可以像以前一样使用onComplete创建回调。

需要注意的重要一点是,一旦你在Future中包装了一些东西,大多数时候你不想取回它。 当您这样做时,它通常位于程序的边缘(例如您的主线程)。

让我们来解决您的问题: val f = Future[List[Future[Users]]] 要取消嵌套,您需要:

f.flatMap(Future.sequence)为您提供Future[List[Users]]

Future.sequence将使Future[List[Future[Users]]]变成Future[Future[List[Users]]] 它将列表中的所有期货合并为一个。 任何失败的未来都会使外部未来成为失败。 如果你不想这样,你可以.recover每个内在的 Future。

f.flatMap将使Future[Future[List[Users]]变成Future[List[Users]] 它在外部 Future 完成后运行内部 Future。 与上面的错误处理相同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM