使用 Scala 和 Play Framework 的嵌套异步调用?
Nested Async calls using Scala and Play Framework?
我想进行嵌套的异步调用。我想在进行第二次异步调用之前执行一次异步调用。第一次异步调用将指示第二次异步调用要执行的参数或操作。
这是原来的异步调用:
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 数组,它是异步 getAuthCookies() 方法的 return 值,请参见下面的示例代码。这些 cookie 需要使用 withCookies() 方法添加到 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() 方法中产生类型不匹配错误。
如何确保 Page.load() 异步方法在 Authenticator.getAuthCookies() 异步方法之后调用,但又不产生类型不匹配错误?
将下一个异步调用(未来)放在 for 理解中。这样您就可以链接调用。假设 Page.load()
returns 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
操作的语法糖。我对 Futures 的介绍可以在这里找到:
我想进行嵌套的异步调用。我想在进行第二次异步调用之前执行一次异步调用。第一次异步调用将指示第二次异步调用要执行的参数或操作。
这是原来的异步调用:
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 数组,它是异步 getAuthCookies() 方法的 return 值,请参见下面的示例代码。这些 cookie 需要使用 withCookies() 方法添加到 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() 方法中产生类型不匹配错误。
如何确保 Page.load() 异步方法在 Authenticator.getAuthCookies() 异步方法之后调用,但又不产生类型不匹配错误?
将下一个异步调用(未来)放在 for 理解中。这样您就可以链接调用。假设 Page.load()
returns 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
操作的语法糖。我对 Futures 的介绍可以在这里找到: