为什么我的地图()不工作?
我有它返回一个字符串,如下所示的阿卡HTTP服务:为什么我的地图()不工作?
val route1: Route = {
path("hello") {
get{
complete{
println("Inside r1")
"You just accessed hello"
}
}
}
}
我想了解地图和flatMap
例如之间的差别,下面的代码给我的结果作为预计:
val future1: Future[String] =
Http()
.singleRequest(
HttpRequest(method = HttpMethods.GET,
uri = "http://localhost:8187/hello"))
.flatMap(testFlatFunc)
def testFlatFunc(x: HttpResponse): Future[String] = {
Unmarshal(x).to[String]
}
但是,如果我试图用地图来取代它,下面我得到的输出为FulfilledFuture(You just accessed hello)
val future1: Future[String] = Http()
.singleRequest(
HttpRequest(method = HttpMethods.GET,
uri = "http://localhost:8187/hello"))
.map(testFunc)
def testFunc(x: HttpResponse): String={
Unmarshal(x).to[String].toString
}
为什么我的map()不能按预期工作?
这是关于你的testFunc
做什么:
def testFunc(x: HttpResponse): String = {
Unmarshal(x).to[String].toString
}
这里的类型是好的,但你在里面做的不是。
Unmarshal(x).to[String]
回报Future[String]
- 这意味着它是异步的结果,它的价值会在第一时间出现在那里。没关系,在flatMap
中使用这样的结果类型。
val sqrts: Double => List[Double] = x => List(Math.sqrt(x), -Math.sqrt(x))
val numbers = List(4.0, 9.0, 16.0)
numbers.flatMap(sqrts) // List(2.0, -2.0, 3.0, -3.0, 4.0, -4.0)
// results equal to
numbers
.map(sqrts) // List(List(2.0, -2.0), List(3.0, -3.0), List(4.0, -4.0))
.flatten // List(2.0, -2.0, 3.0, -3.0, 4.0, -4.0)
在这里你可以看到,flatMap就像地图+扁平化(除了某些容器甚至没有已经实现扁平化,例如Future
;))。
但为什么您的testFunc
失败?基本上,你采取异步结果(Future[String]
),你不等待结果 - 你调用toString而不是只打印一些无用的信息(FulfilledFuture(You just accessed hello)
),但不是结果本身。
要解决这一点,你就必须这样做:
def testFunc(x: HttpResponse): String = {
Await.result(Unmarshal(x).to[String], 10.seconds)
}
这将阻止,最多等待10秒钟,结果,使之同步。(在这种情况下,这种方式胜过目的,如果您计算的结果首先是同步的,则map
会更有用。)
map
和flatMap
区别:
flatMap
就会崩溃嵌套结构的一个级别(它调用fallten),如:List(List(1), List(2)).flatMap(i => i)
将是:List(1, 2)
使你的代码,testFlatFunc
和testFunc
退货类型是Future[String]
和map
和flatMap
函数的返回类型也是Future[T]
,但是flatMap
会使巢结构变平,所以:Future[Future[String]]
会变平为Future[String]
。和map
功能将无法做到这一点,所以:
val future1:Future[String] = Http()
.singleRequest(
HttpRequest(method = HttpMethods.GET,
uri = "http://localhost:8187/hello")).map(testFunc)
返回类型应该是:
val future1:Future[Future[String]] = Http()
.singleRequest(
HttpRequest(method = HttpMethods.GET,
uri = "http://localhost:8187/hello")).map(testFunc)