有一个异步客户端返回列表的期货。为了迭代结果,我需要使用嵌套的map
和flatMap
。是否有一种方法可以创建一个单子转换器,以便能够使用更简单的for推导式,使其看起来像
class MetaClient {
def getDatabases: Future[Seq[String]] = ???
def getTables(database: String): Future[Seq[String]] = ???
def getMeta(database: String, table: String): Future[Meta] = ???
}
object GetMeta {
val client = new MetaClient()
val metas = for {
db <- FutureS(client.getDatabases)
table <- FutureS(client.getTables(db))
meta <- FutureS(client.getMeta(db, table))
} yield meta
val result: Seq[Future[Meta]] = metas.run()
}
val metas: Future[Seq[Meta]] = for {
dbs <- client.getDatabases
tables <- Future.traverse(dbs)(client.getTables)
tablesWithDbs = dbs.zip(tables).flatMap{ case (db, tables) => tables.map((db, _))}
meta <- Future.traverse(tablesWithDbs)((client.getMeta _).tupled)
} yield meta
我认为这样更简单,更容易维护