当函数依赖于未来的某些结果时,我一次又一次地挣扎.这通常归结为像Future [Seq [Future [MyObject]]]这样的结果
为了摆脱这一点,我现在在辅助函数中使用Await来获取非未来的对象并减少嵌套.
看起来像这样
def findAll(page: Int, perPage: Int): Future[Seq[Idea]] = {
val ideas: Future[Seq[Idea]] = collection.find(Json.obj())
// [...]
ideas.map(_.map { // UGLY?
idea => {
// THIS RETURNED A Future[JsObject] before
val shortInfo: JsObject = UserDao.getShortInfo(idea.user_id)
idea.copy(user_data = Some(shortInfo))
}
})
}
Run Code Online (Sandbox Code Playgroud)
这段代码有效,但对我来说它看起来很hacky.这两个地图调用是另一个缺陷.我花了好几个小时试图弄清楚如何保持这种完全异步并返回一个简单的未来Seq.如何使用Play2最佳实践解决这个问题?
编辑 使用例更清晰:
我有一个来自mongodb(reactivemongo)的对象A,并希望添加来自另一个mongodb调用的信息getShortInfo.这是一个经典的"获得此帖子的用户"案例,可以通过加入RDBMS来解决.
getShortInfo因为调用db,自然会产生Future.为了减少嵌套,findAll我使用了Await().这是一个好主意吗?
findAll 从异步Play动作调用,转换为Json并通过线路发送.
def getIdeas(page: Int, perPage: Int) = Action.async {
for {
count <- IdeaDao.count
ideas <- IdeaDao.findAll(page, perPage)
} yield {
Ok(Json.toJson(ideas))
}
} …Run Code Online (Sandbox Code Playgroud) 我是scala的新手,我正在通过一个教程自己工作:http://www.cakesolutions.net/teamblogs/2013/08/02/akka-and-spray/
在某些时候它涉及到测试,它告诉我们可以通过创建结构类型来克服继承要求:
ActorSystem完全实现Core特性.但是,我需要实现Core特性来满足CoreActors的自我类型声明.
我可以将Core定义为结构类型,在这种情况下,我不必担心在这里实现Core.如果您想尝试一下,请删除特征Core {...}并将其替换为
package object core {type Core = {def system:ActorSystem}}这里,Core类型是一种结构类型,它表示Core是包含系统的任何东西:ActorSystem成员.
而且我没有得到这个 - 如果我没有创建一个特性核心,我无法在CoreActors中扩展它 - 我想我在这里错过了一些东西.结构类型的概念对我来说也是新的.