我正在使用 Slick 3.0,以下是我的代码:

def registerMember(newMember: TeamMember): Future[Long] = {

  db.run(
    teamProfileTable.filter(u => u.ID === newMember.ID).result.headOption
  ).flatMap {
    case None => Future(-1)
    case _ => db.run(
      (teamProfileTable returning teamProfileTable.map(_.staffID)) += newMember.toTeamRecord
    )
  }
}

这看起来没问题。但是当回调层数较多时,代码可能会变得难以阅读。我尝试使用 for-expressionandThen 来简化代码..但由于模式匹配部分,我只能使用 flatMap 来实现这一点..

有没有人有关于如何重构这个的想法?

最佳答案

我认为理解在这里应该没问题,您只需要在第一个 Option 的结果中对 Future 进行条件处理。这样的事情应该可以工作(注意我没有编译检查这个):

def registerMember(newMember: TeamMember): Future[Long] = {

  for{
    r1Opt <- db.run(teamProfileTable.filter(u => u.ID === newMember.ID).result.headOption
    r2 <- r1Opt.fold(Future.successful(-1L))(r1 => db.run((teamProfileTable returning teamProfileTable.map(_.staffID)) += newMember.toTeamRecord)
  } yield r2

}

您可以在 fold 的右侧看到,如果第一个 FutureSome (作为 r1 ),我可以访问它的结果。

我什至会更进一步,为理解的步骤创建单独的方法来清理事物,如下所示:
def registerMember(newMember: TeamMember): Future[Long] = {
  def findMember =
    db.run(teamProfileTable.filter(u => u.ID === newMember.ID).result.headOption

  def addMember(r1Opt:Option[TeamMember]) = {
    r1Opt.fold(Future.successful(-1L)){r1 =>
      db.run((teamProfileTable returning teamProfileTable.map(_.staffID)) +=
        newMember.toTeamRecord)
    }
  }

  for{
    r1Opt <- findMember
    r2 <- addMember(r1Opt)
  } yield r2

}

关于scala - 在 Slick 3.0 中,如何简化嵌套 `db.run` ?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30186325/

10-15 18:46