假设我有app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
名为EssentialFilter
,其目的是为每个请求添加标头。但是,要确定需要添加的内容,必须调用返回AbcFilter
的库。我当前实现它的方式使用Future
,因为我需要Await
来完成所以我知道如何构造我需要添加的头。以下是实施:
Future
有没有办法在没有import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.mvc._
import scala.concurrent.duration.{Duration, _}
import scala.concurrent.{Await, Future}
class AbcFilter () extends EssentialFilter {
def apply(nextFilter: EssentialAction) = new EssentialAction {
def apply(requestHeader: RequestHeader) = {
// This call returns a future
val future: Future[String] = asyncLibrary.doSomething(requestHeader)
//Is there any way to avoid using Await here?
val futureResult = Await.result[String](future, Duration(5, SECONDS))
val newHeader = "New-Header-Name"-> futureResult
//I do need the future to complete in order to create this header!
val data = requestHeader.headers.toSimpleMap.toSeq :+ newHeader
val newHeaders = new Headers(_headers = data)
nextFilter(requestHeader.withHeaders(newHeaders))
}
}
}
的情况下实现这个?
答案 0 :(得分:1)
为避免使用Future
,请保持在class AbcFilter () extends EssentialFilter {
def apply(nextFilter: EssentialAction) = new EssentialAction {
def apply(requestHeader: RequestHeader) = {
val newHeaderFut: Future[(String, String)] = asyncLibrary.doSomething(requestHeader)
.map(s => "New-Header-Name" -> s)
val newHeaders: Future[Headers] = newHeaderFut.map(requestHeader.headers.add)
val accumulator: Accumulator[ByteString, Result] = nextFilter(requestHeader)
accumulator.mapFuture { result =>
newHeaders.map(h => result.withHeaders(h.headers: _*))
}
}
}
}
:
{{1}}
答案 1 :(得分:0)
我能够通过使用Filter而不是EssentialFilter并使用flatMap来解决这个问题。 flatMap可以应用于我们在下面的代码示例中得到的第一个未来,但希望这提供了模式的概念。
class AbcFilter () extends Filter{
def apply(nextFilter: RequestHeader => Future[Result])
(requestHeader: RequestHeader): Future[Result] = {
val newHeaderFut: Future[(String, String)] = asyncLibrary.doSomething(requestHeader)
.map(s => "New-Header-Name" -> s)
val newHeaders: Future[Headers] = newHeaderFut.map(requestHeader.headers.add)
newHeaders.flatMap { h => { nextFilter(requestHeader.withHeaders(newHeaders))
}
}
}
}
} }