再次,我对scala的异步性有问题 .
我有以下代码:
Future.sequence {
processSteps.map { step =>
val prerequisiteFuture = processStepPrerequisitesDTO.getProcessStepPrerequisiteIdsByProcessTemplateIdSeq(step.id.get)
prerequisiteFuture.map(prereqs => {
step.prerequisites = Some(prereqs)
println("COPY", step.prerequisites)
})
}
}
processSteps.map { step => {
println("diddled", step.prerequisites)}
}
我怎样才能正确地等待未来 . 顺序完成 . 因为当我尝试打印它们之后它是空的......但它不是......线条同时被调用并且打印比future.sequence更快 .
我不想用Await ......
谢谢 .
UPDATE
这是我的完整控制器函数:def getEditProcessTemplateData(processTemplateId:Int):Action [AnyContent] = Action.async {//获取此过程模板的所有步骤val stepIds:Future [Seq [Int]] = processTemplateDTO.getProcessStepTemplateIds(processTemplateId)
val process = for {
allApprovedProcessTemplates <- processTemplateDTO.getApprovedProcessTemplates //Get all approved process templates
processTemplate <- processTemplateDTO.getProcessTemplate(processTemplateId) // Get the Process Template
prerequisites <- getProcessTemplateForEdit(processPrerequisitesDTO.getProcessPrerequisiteProcessTemplateIdsByProcessTemplateId(processTemplateId))
postConditions <- getProcessTemplateForEdit(processPostConditionsDTO.getProcessPostConditionProcessTemplateIdsByProcessTemplateId(processTemplateId))
approvedProcessTemplate <- processTemplateDTO.getProcessTemplate(processTemplate.get.approveprocess)
trainedProcessTemplate <- processTemplateDTO.getProcessTemplate(processTemplate.get.trainingsprocess)
processSteps <- processTemplateDTO.getProcessStepTemplates(processTemplateId)
// Step prerequisites
processStepsPrerequisites <- getProcessStepsPrerequisites(stepIds)
processStepsPrerequisiteProcessTemplate <- getProcessStepsPrerequisiteProcessTemplate(stepIds)
processTemplatesForStepPrerequisites <- getProcessTemplateForStepPrerequisite(stepIds)
// Step post conditions
processStepsPostConditions <- getProcessStepsPostConditions(stepIds)
processStepPostConditionProcessTemplate <- getProcessStepPostConditionProcessTemplate(stepIds)
processTemplatesForStepPostConditions <- getProcessTemplateForStepPostCondition(stepIds)
// Derived processes
derivedProcesses <- getDerivedProcesses(stepIds)
processTemplatesForStepDerivedProcesses <- getProcessStepsDerivedProcesses(stepIds)
// Process to process step
processStepsTemplates_ProcessTemplates <- getProcessStepsTemplates_ProcessTemplates(stepIds)
processTemplatesForProcessTemplatesToProcessStep <- getProcessTemplateToProcessStepId(stepIds)
responsible <- raciProcessTemplateDTO.getResponsibleProcessTemplates(processTemplateId) // get all responsibles for this process template
accountable <- raciProcessTemplateDTO.getAccountableProcessTemplates(processTemplateId) // get all accountables for this process template
consulted <- raciProcessTemplateDTO.getConsultedProcessTemplates(processTemplateId) // get all consulted for this process template
informed <- raciProcessTemplateDTO.getInformedProcessTemplates(processTemplateId) // get all consulted for this process template
} yield (allApprovedProcessTemplates, processTemplate, prerequisites, postConditions, processSteps, processStepsPrerequisites,
processStepsPrerequisiteProcessTemplate, processTemplatesForStepPrerequisites, processStepsPostConditions, processStepPostConditionProcessTemplate, processTemplatesForStepPostConditions, derivedProcesses,
processTemplatesForStepDerivedProcesses, processStepsTemplates_ProcessTemplates, processTemplatesForProcessTemplatesToProcessStep, approvedProcessTemplate, trainedProcessTemplate, responsible, accountable, consulted, informed)
process.map({ case (allApprovedProcessTemplates, processTemplate, prerequisites, postConditions, processSteps, processStepsPrerequisites,
processStepsPrerequisiteProcessTemplate, processTemplatesForStepPrerequisites, processStepsPostConditions, processStepPostConditionProcessTemplate, processTemplatesForStepPostConditions, derivedProcesses,
processTemplatesForStepDerivedProcesses, processStepsTemplates_ProcessTemplates, processTemplatesForProcessTemplatesToProcessStep, approvedProcessTemplate, trainedProcessTemplate, responsible, accountable, consulted, informed) =>
val sequenced = Future.sequence {
processSteps.map { step =>
val prerequisiteFuture = processStepPrerequisitesDTO.getProcessStepPrerequisiteIdsByProcessTemplateIdSeq(step.id.get)
prerequisiteFuture.map(prereqs => {
step.prerequisites = Some(prereqs)
println("COPY", step.prerequisites)
})
}
}
sequenced.map { items => {
println(items)}
}
Ok(Json.obj(
"allApprovedProcessTemplates" -> allApprovedProcessTemplates,
"processTemplate" -> processTemplate,
"prerequisites" -> prerequisites,
"postConditions" -> postConditions,
"approvedProcessTemplate" -> approvedProcessTemplate,
"trainedProcessTemplate" -> trainedProcessTemplate,
// Step prerequisites
"processStepsPrerequisites" -> processStepsPrerequisites,
"processStepsPrerequisiteProcessTemplate" -> processStepsPrerequisiteProcessTemplate,
"processTemplatesForStepPrerequisites" -> processTemplatesForStepPrerequisites,
// Step post conditions
"processStepsPostConditions" -> processStepsPostConditions,
"processStepPostConditionProcessTemplate" -> processStepPostConditionProcessTemplate,
"processTemplatesForStepPostConditions" -> processTemplatesForStepPostConditions,
// Derived processes
"derivedProcesses" -> derivedProcesses,
"processTemplatesForStepDerivedProcesses" -> processTemplatesForStepDerivedProcesses,
// Process to process step
"processStepsTemplates_ProcessTemplates" -> processStepsTemplates_ProcessTemplates,
"processTemplatesForProcessTemplatesToProcessStep" -> processTemplatesForProcessTemplatesToProcessStep,
"steps" -> processSteps,
"responsible" -> responsible,
"accountable" -> accountable,
"consulted" -> consulted,
"informed" -> informed
))
})
}
2 回答
您需要了解的几件事情:
prerequisiteFuture.map(prereqs => { step.prerequisites = Some(prereqs) println("COPY", step.prerequisites) })
将返回Future [Unit],因为println()的返回类型是Unit .
List[Future[A]]
转换为Future[List[A]]
.因此,在上面的示例中,您创建了一个将打印但不会返回任何内容的未来 . 后来你只是打印这些步骤 .
由于未来会延迟,因此输出将为
diddled
,然后是COPY
.如果要在复制后执行diddled,则应使用
future.map()
. 像这样你能试一试吗:
?
------------------------------------- UPDATE ------------ -------------
你没有提供关于这个代码所在位置的任何上下文 . 所以如果你想让它最终在控制台中打印,你需要确保你所拥有的主线程或任何线程仍在运行时序列完成 . 这是一个简化的例子:import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global
产生以下控制台输出:
但在此示例中仅使用
Thread.sleep
或Await
才能在控制台中显示结果 . 你最初的问题是你把期货的seq包装成了Future.sequence
但是之后你仍然试图使用内部seq,你从未使用Future.sequence
未来的实例创建 .我认为在您的代码中,您将生成的未来传递给更高的上下文,因此您需要检查和
println
,如果这是例如网络应用程序 .如果考虑到上面的所有内容,它仍会打印空向量 - 那么这意味着向量确实是空的,因此您需要在本地调试并找出原因 .