YoT*_*YoT 11 web-services scala promise akka playframework-2.0
我在PlayFramework2/Scala中开发了一个小服务器,它必须从多个WS(REST/JSON)中检索数据,操纵来自这些WS的数据,然后编写并返回结果.
我知道如何调用一个 WS,操纵数据并返回异步响应.但我不知道如何连续调用多个Web服务,在每次调用之间处理数据并生成聚合答案.
例如:
我被WS API(WS.url(url).get => Promise[Response]
)的异步处理阻止了.我是否必须依靠Akka来解决这个问题?
谢谢.
Jul*_*Foy 19
flatMap
并且map
是你的朋友!这两种Promise
类型的方法允许将a的结果转换Promise[A]
为另一种Promise[B]
.
这是一个简单的实例示例(我故意明确地写了比需要更多的类型注释,只是为了帮助理解转换发生的位置):
def preferredSongsAndArtist = Action {
// Fetch the list of your preferred songs from Web Service “A”
val songsP: Promise[Response] = WS.url(WS_A).get
val resultP: Promise[List[Something]] = songsP.flatMap { respA =>
val songs: List[Song] = Json.fromJson(respA.json)
// Then, for each song, fetch the artist detail from Web Service “B”
val result: List[Promise[Something]] = songs.map { song =>
val artistP = WS.url(WS_B(song)).get
artistP.map { respB =>
val artist: Artist = Json.fromJson(respB.json)
// Then, generate and return something using the song and artist
val something: Something = generate(song, artist)
something
}
}
Promise.sequence(result) // Transform the List[Promise[Something]] into a Promise[List[Something]]
}
// Then return the result
Async {
resultP.map { things: List[Something] =>
Ok(Json.toJson(things))
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果没有不必要的类型注释并使用"for comprehension"表示法,您可以编写以下更具表现力的代码:
def preferredSongsAndArtist = Action {
Async {
for {
// Fetch the list of your preferred songs from Web Service “A”
respA <- WS.url(WS_A).get
songs = Json.fromJson[List[Song]](respA.json)
// Then, for each song, fetch the artist detail from Web Service “B”
result <- Promise.sequence(songs.map { song =>
for {
respB <- WS.url(WS_B(song)).get
artist = Json.fromJson[Artist](respB.json)
} yield {
// Then, generate and return something using the song and artist
generate(song, artist)
}
})
// Then return the result
} yield {
Ok(Json.toJson(result))
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4121 次 |
最近记录: |