2017-09-14 101 views
0

,我再次与斯卡拉的asyncronousity问题。playframework斯卡拉如何等待asyncronousity

我有以下代码:

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.sequnce要完蛋。因为当我试图在后面打印它的空白...但它不是......线条被同时调用并且打印速度比将来快。序列。

我不想使用等待...

谢谢。

UPDATE

这里是我的全部控制器功能: 高清getEditProcessTemplateData(processTemplateId:智力):操作[AnyContent] = {Action.async // 得到这个流程模板 VAL stepIds的所有步骤:未来[序列[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 
)) 
}) 
} 
+0

processSteps的类型是什么? –

+0

撰写,而不是等待异步(这使得它同步,所以..) – cchantep

回答

1

一些事情你需要了解:

  1. 函数/λ的返回类型由函数的最后一个语句定义,如果在功能没有return语句。 因此函数

    prerequisiteFuture.map(prereqs => { step.prerequisites = Some(prereqs) println("COPY", step.prerequisites) })

    将返回未来[单位],由于的println的返回类型()是单位。

  2. Future.sequence将List[Future[A]]转换为Future[List[A]]

所以在上面的例子中,你创建了一个将来打印但不会返回任何东西。 然后你只是在打印这些步骤。

由于未来延迟,产量将为diddled,然后是COPY

如果您想要在副本后执行diddled,则应使用future.map()。像这样

Future.sequence {processSteps.map { 
    step => 
     val prerequisiteFuture = processStepPrerequisitesDTO 
      .getProcessStepPrerequisiteIdsByProcessTemplateIdSeq(step.id.get) 
     prerequisiteFuture.map(prereqs => { 
      step.prerequisites = Some(prereqs) 
      println("COPY", step.prerequisites) 
      step.prerequisites 
     }) 
     } 
    }.map { 
     items => 
     items.map { step => 
     println("diddled", step.prerequisites) 
     } 
     Ok("your json response here") 
    } 
+0

。 .concurrent.Future [?]' – Felix

+0

我的bad代替flatMap它应该是map。 –

+0

抱歉不编译。'''重载的方法值异步与替代: [error](block:play.api.mvc.Request [ play.api.mvc.AnyContent] => scala.concurrent.Future [play.api.mvc.Result])play .api.mvc.Action [play.api.mvc.AnyContent] [error](block:=> scala.concurrent.Future [play.api.mvc.Result])play.api.mvc.Action [play。 api.mvc.AnyContent] [error]无法应用(scala.concurrent.Future [play.api.mvc.Result]]) [error] def getEditProcessTemplateData(processTemplateId:Int):Action [AnyContent] = Action.async { ''' – Felix

1

你能试试这个:

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 => 
    items foreach (println("diddled", _.prerequisites)) 
} 

-------------------------------------更新-------- -----------------

您没有提供在何处这个地方的代码确实运行在任何情况下。因此,如果你希望它最终被印在控制台你当序列中的所有期货都完成时,确实需要确保主线或任何线程仍在运行。 下面是一个简化的例子: 进口scala.concurrent.Future 进口scala.concurrent.ExecutionContext.Implicits.global

object Test { 

    def main(args:Array[String]):Unit = { 
    val sequence = Seq(Future({Thread.sleep(100); 1}), Future({Thread.sleep(200); 2})) 

    val sequenced = Future.sequence(sequence) 

    sequenced foreach(items => items foreach(println(_))) 

    Thread.sleep(1000) 
    } 
} 

将会产生以下控制台输出:

1 
2 

Process finished with exit code 0 

但是使用Thread.sleep或本例中的Await仅用于在控制台中显示结果。 您最初的问题是,你包裹期货以次为Future.sequence但之后,你仍然试图与内部以次工作,你从来没有使用过这个未来的Future.sequence实例创建。

我认为在你的代码中传递导致未来高一些情境,所以你需要检查和println那里,如果这是如网络应用程序。

如果采取上述一切考虑它仍然打印空白载体 - 那么就意味着矢量的确是空的,所以你需要在本地进行调试,并找出原因。

+0

我得到这个消息'缺少参数类型的扩展功能((x $ 12)=> x $ 12.prerequisites)'右'_.prerequisites' – Felix

+0

当我这样做'sequenced.map {items => {println(items)} }'打印一个空的Vector(((),()) – Felix

+1

我已经更新了我的答案。你还没有使用'Future.sequence'应用程序的结果。这是主要问题。剩下的我不能为你工作,因为我不知道这段代码在哪里运行,以及你将结果传递到哪里。 简化的示例向您显示“Future.seqence”用法的正确语义。 –