如何结合Scala中的2个期货

Nay*_*aya 0 scala future

我正在写一个CRUD rest api,并且遇到了在服务层合并2个期货的问题.

我们的想法是将实体插入到db中,然后通过id检索由db值生成的所有内容.

我尝试了和Java一样,但它不能返回Future [Entity],它说它仍然是Future [Long]

class Service {
  def find(id: Long): Future[Option[Entry]] = db.run(repo.findEntry(id))

  //TODO Fails: Expression of type Future[Long] doesn't conform to expected type Future[Option[Entity]]
  def insert(): Future[Option[Entry]] = db.run(repo.insertEntry())
            .andThen { case Success(id) =>
                find(id)
            }
}

class Repository {
  def findEntry(id: Long): DBIO[Option[Entry]] =
    table.filter(_.id === id).result.headOption

  def insertEntry()(implicit ec: ExecutionContext): DBIO[Long] =
    table returning table.map(_.id) += Entry()
}
Run Code Online (Sandbox Code Playgroud)

我觉得答案很简单,但是找不到它.

Thi*_*ilo 6

andThen 对于副作用,它仍然返回原始结果(第一个Future).

你想要的flatMap.

 db.run(repo.insertEntry())
   .flatMap( id => find(id) )
Run Code Online (Sandbox Code Playgroud)

flatMap 还附带了一个特殊的语法,大多数人发现它们更具可读性(在他们习惯之后),特别是如果有更多的步骤:

 for {
   id <- db.run(repo.insertEntry())
   entry <- find(id)
 } yield entry
Run Code Online (Sandbox Code Playgroud)

  • 试图将`yield id`编辑为`yield entry`,因为它似乎是一个明显的拼写错误,但是scala或相关FP标签中没有活动的几个用户都拒绝了它.我有点恼怒,所以如果他们同意的话,就给回答者或更高的业力scala用户留下评论. (2认同)