使用Scala和Play Framework进行嵌套异步调用?

时间:2015-06-01 15:01:25

标签: scala cookies asynchronous playframework playframework-2.0

我想进行嵌套异步调用。我想在进行第二次异步调用之前执行一次异步调用。第一次异步调用将指示第二次异步调用要采取的参数或操作。

这是原始的异步调用:

def render(param1:String) = Action.async { request =>
  implicit val ctx = RequestContext.createFromRequest(request)
  Page.load(param1, request).map {
      case PageType1(title) =>
        Ok(views.html.main("pageType1", title))
      case PageType2(title) =>
        Ok(views.html.main("pageType2", title))
  }
}

我想在Page.load()异步调用异步验证登录用户信息之前执行的异步。如果用户未登录,则会创建未经身份验证的匿名令牌。此信息需要写入一个cookie数组,这是async getAuthCookies()方法的返回值,请参阅下面的示例代码。需要使用withCookies()方法将这些cookie添加到Ok()方法中。 (最终我还可以根据getAuthCookies()方法中收集的信息更改代码流,以便在用户的会话过期时创建用户登录页面。)这可能是更多背景信息关于必要的代码,但希望通用代码示例足以让您了解我想要做的事情。

请参阅以下有关getAuthCookies()方法的异步调用:

  ...
  implicit val ctx = RequestContext.createFromRequest(request)
  for {
      cookies <- Authenticator.getAuthCookies(request) 
  } yield {
     //Placing Page.load() here doesn't work. It produces a type mismatch err
  }
  ...

我试图将Page.load()代码放在yield语句中,但是在更通用的render()方法中会产生类型不匹配错误。

如何确保在Authenticator.getAuthCookies()异步方法之后调用Page.load()异步方法,但确保不会产生类型不匹配错误?

1 个答案:

答案 0 :(得分:1)

将下一个异步调用(Future)放在中进行理解。这样你可以链接呼叫。我们假设Page.load()返回Future[Page]page值下面的代码将Page而不是Future[Page]。这种方式Page.load()getAuthCookies方法之后被称为

 ...
  implicit val ctx = RequestContext.createFromRequest(request)
  for {
      cookies <- Authenticator.getAuthCookies(request)
      page <- Page.load()
  } yield {
  }
  ...

另请注意,因为理解只是flatMap操作的语法糖。我可以在这里找到期货的好介绍:

http://danielwestheide.com/blog/2013/01/09/the-neophytes-guide-to-scala-part-8-welcome-to-the-future.html