我有一个函数来获取一个给定JobIds的workItemIds,并带有以下签名 -
def getWorkItemIds(jobId: JobId): Future[Seq[WorkItemId]]
我有另一个函数,给定WorkItemId会返回一个workItem。签名 -
def getWorkItem(workItemId: WorkItemId): Future[Option[WorkItem]]
现在我正在尝试编写一个函数,使用这两个函数返回一个给定JobId的WorkItem的seq,就像这样 -
def getWorkItemsForJob(jobId: JobId): Future[Seq[Future[Option[WorkItem]]]] = {
val workItemIds: Future[Seq[WorkItemId]] = getWorkItemIds(jobId)
val res = workItemIds.map {
idSeq => idSeq.map {
id => getWorkItem(id)
}
}
res
}
问题是返回类型,我不想返回这个怪异的类型,而应该返回像Future[Seq[WorkItem]]
这样简单的东西。现在我可以像 -
def getWorkItemsForJob(jobId: JobId): Future[Seq[WorkItem]] = {
val workItemIds: Future[Seq[WorkItemId]] = getWorkItemIds(jobId)
val res = workItemIds.map {
idSeq => idSeq.flatMap {
id => getWorkItem(id).get
}
}
res
}
它为我提供了我想要的正确Future[Seq[WorkItem]]
类型,但它要求我对未来有所了解,这感觉不正确。我也可以使用await但这将是一个阻塞调用。反正是否有上述类型而没有阻塞?
答案 0 :(得分:3)
您要找的是Future.traverse
:
def getWorkItemsForJob(jobId: JobId): Future[Seq[WorkItem]] =
getWorkItemIds(jobId).flatMap(Future.traverse(_)(getWorkItem).map(_.flatten))
.traverse
来电从Seq
来看getWorkItemIds
,并在每个条目上返回Future[Seq]
调用getWorkItem
的结果,没有内在Future
包裹。
靠近末尾的.map(_.flatten)
将内部Seq[Option[WorkItem]]
展平为Seq[WorkItem]
。
答案 1 :(得分:3)
您可以通过以下方式执行此操作:
def getWorkItemsForJob(jobId: JobId): Future[Seq[WorkItem]] =
for (
seq <- getWorkItemIds(jobId);
list <- Future.traverse(seq)(getWorkItem)
) yield list.flatten