【问题标题】:Scala Aggregate result from multiple Future calls来自多个 Future 调用的 Scala 聚合结果
【发布时间】:2016-02-29 21:43:41
【问题描述】:

考虑一个用于集群主/从选举的模型。

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 可以做到的最好的吗?

谢谢。

【问题讨论】:

    标签: scala concurrency playframework future


    【解决方案1】:

    你手头已经有会员了,为什么还要做 MemberDao.findById ??? (您也将退货视为会员,而它实际上应该是 Option[Member])。 此外,更新不需要将 id 作为单独的参数(member 中有一个可用的参数)。 你不需要Await你的结果,因为你的函数返回一个Future,你不需要返回一个Boolean:只需抛出一个异常来表示失败。 考虑这样的事情:

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

    没那么臃肿吧? :)

    【讨论】:

    • 很有意义,这里显然是一个新手 scala 开发人员,还有一个问题,memberDao.update 接受的是一个成员,而不是 Future[Member],这是 memberDao.all 将返回的。所以我猜我还需要做 memberFuture => 映射吗?
    • 不,在您的定义中 .all 返回一个 Future[List[Member]]。我的 sn-p 中的第一个 .flatMapFuture 内部查找,然后 foreach 遍历 Member 的列表。但请注意,我已经更新了修复返回类型不兼容的答案:您需要在 .flatMap 中使用 Future.sequence 将期货列表转换为未来列表,然后最后的 .map 丢弃要制作的列表结果Future[Unit] 而不是Future[List[Unit]]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 2010-11-17
    • 2020-08-20
    • 2019-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多