Scala HttpService上的wait.result
我有一个scala项目,其中包含http4s 0.15.16a和slick 3.2.1,包括以下步骤:Scala HttpService上的wait.result,scala,future,slick-3.0,http4s,http4s-circe,Scala,Future,Slick 3.0,Http4s,Http4s Circe,我有一个scala项目,其中包含http4s 0.15.16a和slick 3.2.1,包括以下步骤: 通过rest呼叫接收ID 将ID传递给MySlickDAO,并用未来进行响应 调用myclickdao返回的Future上的wait.result(res,Duration.Inf) 创建json 问题是我使用了Await.result,这是不好的做法 有更好的解决办法吗 代码如下: val service = HttpService { //http://localhost:8080/
val service = HttpService {
//http://localhost:8080/rest/id/9008E75A-F112-396B-E050-A8C08D26075F
case GET -> Root / "rest" / "id" / id =>
val res = MySlickDAO.load(id)
Await.result(res, Duration.Inf)
val ll = res.value.get.get
ll match {
case Failure(x) =>
InternalServerError(x)
case Success(record) =>
val r = record.map(x => MyEntity(x._1, x._2, x._3))
jsonOK(r.asJson)
}
case ....
}您可以将一个
未来的结果链接到另一个而不是等待:
val resFut = MySlickDAO.load(id)
resFut.map { record =>
val r = record.map(x => MyEntity(x._1, x._2, x._3))
jsonOK(r.asJson)
} recover { x =>
InternalServerError(x)
}
这样做的结果将是未来
的一个常见超类型jsonOK
和InternalServerError
(不熟悉您正在使用的库;因此我可能有错误的加载类型:这不是未来[Try[\u]]
是吗?)
顺便说一句:您的原始代码有一行非常有问题:
val ll = res.value.get.get
res.value
是一个选项[Try[T]]
。在选项
或尝试
上调用获取
通常是个坏主意(即使在这种情况下,由于等待
,选项
永远不应该是无
,因此获取
在技术上是安全的),因为它可能引发异常。您最好使用map
、flatMap
和friends。问题是,http4s 0.15使用Scalaz并发结构,而Slick使用本机Scala结构,这两种结构不适合彼此工作。我的理解是,http4s0.17+已经从Scalaz转换为Cats,这可能需要使用原生Scala期货,因此如果您可以升级,这可能值得一试。如果没有,您可以通过手动创建一个包装您未来的任务来处理转换:
def scalaFutureRes = MySlickDAO.load(id)
val scalazTaskRes = Task.async { register =>
scalaFutureRes.onComplete {
case Success(success) => register(success.right)
case Failure(ex) => register(ex.left)
}
}
此时,您已经从未来的[ResultType]中获得了一个任务[ResultType],您可以将其映射/平面映射到您的其余逻辑,如Levi的回答中所示
您也可以使用这个库,它通过隐式转换在相关类上定义了这个逻辑和相反的方向,这样您就可以在将来调用.toTask以获得兼容的形式。他们的自述文件中也有很多关于转换和陷阱的有用信息。为什么要将未来
阻塞?@cchantep我等待未来完成为什么?这不是使用Future
(它已经失去了所有的兴趣)的通常方式。jsonOK是OK:defjsonok(s1:Json)的包装器:Task[Response]=OK(removeNull(s1))。putHeaders(Header(“内容类型”,“应用程序/Json”)等等?这仍然是阻塞(还有不安全的.get
)map返回未来而不是任务[Response],因此问题仍然存在:scala.concurrent.Future[scalaz.concurrent.Task[org.http4s.Response]]required:scalaz.concurrent.Task[org.http4s.Response]resFut.map{record=>