2017-09-14 95 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」用法的正確語義。 –