考虑一个群集的主/从选举模型。
Member{ id: Long, isMaster: Boolean }
我有以下方法的Dao / Repo:
MemberDao.findById(id:Long):Future[Option[Member]]
MemberDao.update(id:Long, member: Member):Future[Unit]
MemberDao.all() : Future[List[Member]]
在MemberService中,我试图编写一个函数来为所有现有成员将isMaster设置为false,并且我最终得到了这个疯狂膨胀的代码:
class MemberService ... {
def demoteAllMembers() : Future[Boolean] = {
val futures = memberDao.all.map{ memberFuture =>
memberFuture.map{ member =>
memberDao.findById(member.id).map { existingMemberFuture =>
existingMemberFuture.map { existingMember =>
memberDao.update(existingMember.id, existingMember.copy(isMaster = false)
}
}
}
val results = Await.result(futures, 10 seconds)
// return something here
}
}
}
我的问题是: 1.如何编写return语句来处理成功/错误?例如成功后,返回Future(true)并在失败时返回Future(false) 2.这种重复映射未来在scala中进行异步编程的正确方法吗?我理解这可以在Actor范例中以不同的方式编写,可能要好得多,但是在OOP的情况下,这是最好的Scala可以做到的吗?
感谢。
答案 0 :(得分:2)
当你手里拿着一个成员时,你为什么要成员D.dind.findById? (您也将会员作为会员处理,而它应该是一个选项[会员])。
此外,更新不需要将id作为单独的参数(member
内有一个可用)。
您不需要Await
您的结果,因为您的函数返回Future
,并且您不需要返回Boolean
:只需抛出异常即可信号失败。
考虑这样的事情:
def demoteAllMembers: Future[Unit] = memberDao.all.flatMap {
Future.sequence(_.foreach {
memberDao.update(_.copy(isMaster = false))
})
}.map ( _ => () )
不是那么臃肿,是吗? :)