Scala 仅当将来的计算完成时才返回页面
我的应用程序中有一个使用Play Framework的控制器Scala 仅当将来的计算完成时才返回页面,scala,playframework,Scala,Playframework,我的应用程序中有一个使用Play Framework的控制器 def controllerMethod() = Action{ val someval = callToService() Ok(views.html.abc(someval)) } 服务类中的callToService方法: 当我从for循环中调用webservice时,比如说5次,每次我都在somerandomobject中设置一个属性。因为for循环中有一个webservice调用,它返回一个未来的[Response
def controllerMethod() = Action{
val someval = callToService()
Ok(views.html.abc(someval))
}
服务类中的callToService方法:
当我从for循环中调用webservice时,比如说5次,每次我都在somerandomobject中设置一个属性。因为for循环中有一个webservice调用,它返回一个未来的[Response],所以控制器返回页面时甚至没有得到someval的值,并且页面上没有显示任何数据
为了防止出现这种情况,我将块置于wait.resultfuture、timeout中,并给出了一些超时。这是个坏主意。我还可以做些什么,以便控制器仅在someval对象可用后返回页面?选项1:
您可以通过组合从web服务返回的future,从callToService返回future。因此callToService将具有Future[SomeRandomObject]的返回类型,并将def更改为some
备选案文2:
对从webservice返回的future使用Await.result,其余代码将保持不变。但此选项阻止了选项1:
您可以通过组合从web服务返回的future,从callToService返回future。因此callToService将具有Future[SomeRandomObject]的返回类型,并将def更改为some
备选案文2:
对从webservice返回的future使用Await.result,其余代码将保持不变。但是这个选项阻碍了我认为你误解了Play如何使用期货的本质。未来不需要在函数退出时完成,因为函数本身可以返回未来 假设您的服务中有一个函数,它返回一个包含字符串的Future:
def getSingleResult: Future[String]
要在控制器中处理此问题,可以将未来的成功完成映射到结果字符串
def singleSource = Action.async {
// send the string in the body of a 200 response
getSingleResult.map(str => Ok(str))
}
现在,假设您正在调用5个web服务,并且希望同时在控制器中处理结果。在本例中,webServiceX函数表示对web服务的调用;因为这些示例函数返回期货,所以我们得到了相同的效果
def webServiceCallA: Future[String] = // implementation
def webServiceCallB: Future[Int] = // implementation
def webServiceCallC: Future[Boolean] = // implementation
def webServiceCallD: Future[Foo] = // implementation
def webServiceCallE: Future[Bar] = // implementation
我们可以使用for comprehension来完成这些未来,并构造SomeRandomClass的实例来返回结果
case class SomeRandomClass(a: String, b: Int, c: Boolean, d: Foo, e: Bar)
def getUsingForComprehension: Future[SomeRandomObject] = {
val eventualA = webServiceCallA
val eventualB = webServiceCallB
val eventualC = webServiceCallC
val eventualD = webServiceCallD
val eventualE = webServiceCallE
for {
a <- eventualA
b <- eventualB
c <- eventualC
d <- eventualD
e <- eventualE
} yield SomeRandomClass(a, b, c, d, e)
}
在任何时候,我们都不会阻止或明确等待未来的完成 我认为你误解了游戏如何利用未来的本质。未来不需要在函数退出时完成,因为函数本身可以返回未来 假设您的服务中有一个函数,它返回一个包含字符串的Future:
def getSingleResult: Future[String]
要在控制器中处理此问题,可以将未来的成功完成映射到结果字符串
def singleSource = Action.async {
// send the string in the body of a 200 response
getSingleResult.map(str => Ok(str))
}
现在,假设您正在调用5个web服务,并且希望同时在控制器中处理结果。在本例中,webServiceX函数表示对web服务的调用;因为这些示例函数返回期货,所以我们得到了相同的效果
def webServiceCallA: Future[String] = // implementation
def webServiceCallB: Future[Int] = // implementation
def webServiceCallC: Future[Boolean] = // implementation
def webServiceCallD: Future[Foo] = // implementation
def webServiceCallE: Future[Bar] = // implementation
我们可以使用for comprehension来完成这些未来,并构造SomeRandomClass的实例来返回结果
case class SomeRandomClass(a: String, b: Int, c: Boolean, d: Foo, e: Bar)
def getUsingForComprehension: Future[SomeRandomObject] = {
val eventualA = webServiceCallA
val eventualB = webServiceCallB
val eventualC = webServiceCallC
val eventualD = webServiceCallD
val eventualE = webServiceCallE
for {
a <- eventualA
b <- eventualB
c <- eventualC
d <- eventualD
e <- eventualE
} yield SomeRandomClass(a, b, c, d, e)
}
在任何时候,我们都不会阻止或明确等待未来的完成