Scala 聚合多个 Future 调用的结果

Scala Aggregate result from multiple Future calls

考虑 Master/Slave 集群选举的模型。

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语句应该如何写来处理成功/错误?例如成功时,return Future(true) 失败时,return Future(false) 2. 这种重复映射 future 的方式是否是在 scala 中进行异步编程的正确方式?我知道这在 Actor 范式中可以有不同的写法并且可能更好,但是在 OOP 的情况下,这是 Scala 能做的最好的吗?

谢谢。

手上已经有会员了,为什么还要MemberDao.findById??? (您还将 return 视为成员,而它实际上应该是一个选项 [成员])。 另外,update 不需要将 id 作为一个单独的参数(member 中有一个可用)。 你不需要 Await 你的结果,因为你的函数是 returning a Future,你不需要 return a Boolean:只是抛出一个异常来表示失败。 考虑这样的事情:

def demoteAllMembers: Future[Unit] = memberDao.all.flatMap { 
   Future.sequence(_.foreach {
     memberDao.update(_.copy(isMaster = false))
   })
 }.map ( _ => () ) 

没那么臃肿吧? :)