Scala Play:如何等到将来完成,然后再将OK结果返回到前端 [英] Scala Play: how to wait until future is complete before OK result is returned to frontend

查看:91
本文介绍了Scala Play:如何等到将来完成,然后再将OK结果返回到前端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的playframework应用程序中,我想等到我的未来完成并返回到视图中.

In my playframework application I want to wait until my future is completed and the return it to the view.

我的代码如下:

 def getContentComponentUsageSearch: Action[AnyContent] = Action.async { implicit request =>
    println(request.body.asJson)
    request.body.asJson.map(_.validate[StepIds] match {
      case JsSuccess(stepIds, _) =>

        println("VALIDE SUCCESS -------------------------------")


        val fList: List[Seq[Future[ProcessTemplatesModel]]] = List() :+ stepIds.s.map(s => {
          processTemplateDTO.getProcessStepTemplate(s.processStep_id).flatMap(stepTemplate => {
            processTemplateDTO.getProcessTemplate(stepTemplate.get.processTemplate_id.get).map(a => {
              a.get
            })
          })
        })


        fList.map(u => {
          val a: Seq[Future[ProcessTemplatesModel]] = u

          Future.sequence(a).map(s => {
            println(s)
          })
        })


        Future.successful(Ok(Json.obj("id" -> "")))

      case JsError(_) =>
        println("NOT VALID -------------------------------")
        Future.successful(BadRequest("Process Template not create client"))
      case _ => Future.successful(BadRequest("Process Template create client"))
    }).getOrElse(Future.successful(BadRequest("Process Template create client")))
  }

pirntln(s)正在打印完成的东西.但是如何等待它完成,然后将其返回视图?

the pirntln(s) is printing the finished stuff. But how can I wait until it is complete and return it then to the view?

预先感谢

更新:

也尝试过这个:

  val process = for {

      fList: List[Seq[Future[ProcessTemplatesModel]]] <- List() :+ stepIds.s.map(s => {
        processTemplateDTO.getProcessStepTemplate(s.processStep_id).flatMap(stepTemplate => {
          processTemplateDTO.getProcessTemplate(stepTemplate.get.processTemplate_id.get).map(a => {
            a.get
          })
        })
      })

    } yield (fList)





    process.map({ case (fList) =>
      Ok(Json.obj(
        "processTemplate" -> fList
      ))
    })

但后来我明白了:

更新: 我的问题是fList中的期货在返回OK结果之前没有完成

UPDATE: My problem is that the futures in fList do not complete before an OK result is returned

推荐答案

问题中的代码似乎不可编译,因此这是未经测试的非常粗略的草图,希望可以为进一步搜索正确的解决方案提供足够的启发:

The code in the question didn't seem compilable, so here is an untested very rough sketch, that hopefully provides enough inspiration for further search of the correct solution:

def getContentComponentUsageSearch: = Action.async { implicit req =>
  req.body.asJson.map(_.validate[StepIds] match {
    case JsSuccess(stepIds, _) => {

      // Create list of futures
      val listFuts: List[Future[ProcessTemplatesModel]] = (stepIds.s.map(s => {
        processTemplateDTO.
          getProcessStepTemplate(s.processStep_id).
          flatMap{ stepTemplate => 
            processTemplateDTO.
              getProcessTemplate(stepTemplate.get.processTemplate_id.get).
              map(_.get)
          }
      })).toList

      // Sequence all the futures into a single future of list
      val futList = Future.sequence(listFuts)

      // Flat map this single future to the OK result
      for {
        listPTMs <- futList
      } yield {
        // Apparently some debug output? 
        listPTMs foreach printl

        Ok(Json.obj("id" -> ""))
      }
    }

    case JsError(_) => {
      println("NOT VALID -------------------------------")
      Future.successful(BadRequest("Process Template not create client"))
    }

    case _ => Future.successful(BadRequest("Process Template create client"))

  }).getOrElse(Future.successful(BadRequest("Process Template create client")))
}

如果我正确理解了您的问题,那么您要确保在返回确定之前,确保列表中的所有期货均已完成.因此,我首先创建了List[Future[...]]:

If I understood your question correctly, what you wanted was to make sure that all futures in the list complete before you return the OK. Therefore I have first created a List[Future[...]]:

  val listFuts: List[Future[ProcessTemplatesModel]] = // ...

然后,我将所有期货合并到一个列表的期货中,该清单仅在每个元素都已完成时才完成:

Then I've combined all the futures into a single future of list, which completes only when every element has completed:

  // Sequence all the futures into a single future of list
  val futList = Future.sequence(listFuts)

然后,我使用for -comprehension来确保listPTMs在返回OK之前完成计算:

Then I've used a for-comprehension to make sure that the listPTMs finishes computation before the OK is returned:

  // Flat map this single future to the OK result
  for {
    listPTMs <- futList
  } yield {
    // Apparently some debug output? 
    listPTMs foreach printl

    Ok(Json.obj("id" -> ""))
  }

for-yield(在此等同于map)是建立完成行为的先决条件,以便在构造OK之前对listPTMs进行全面评估.

The for-yield (equivalent to map here) is what establishes the finish-this-before-doing-that behavior, so that listPTMs is fully evaluated before OK is constructed.

这篇关于Scala Play:如何等到将来完成,然后再将OK结果返回到前端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆