Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala Playframework中期货的Cache.getOrElse_Scala_Caching_Playframework 2.0 - Fatal编程技术网

Scala Playframework中期货的Cache.getOrElse

Scala Playframework中期货的Cache.getOrElse,scala,caching,playframework-2.0,Scala,Caching,Playframework 2.0,在playframework中缓存未来结果的正确方法是什么。例如: val userGravatar: Future[JsValue] = RemoteGravatarService.get(user.id, user.email) object RemoveGravatarService { def get(userId: String, email: String): Future[JsValue] = { Cache.getOrElse("gravatar-for-$user

在playframework中缓存未来结果的正确方法是什么。例如:

val userGravatar: Future[JsValue] = RemoteGravatarService.get(user.id, user.email)

object RemoveGravatarService {
  def get(userId: String, email: String): Future[JsValue] = {
    Cache.getOrElse("gravatar-for-$userId", 1.hour) {
      WS.url("gravatar.com/email=$email").get().asJson
    }
  }
}
我们不想每次都问(这个虚构的)“Gravatar”,因为它不会经常改变。但我们经常需要本地的som userGravatar信息


这里我们缓存未来本身,但实际上我们只想缓存未来的结果。在游戏中是否有一种方便/正确的方法来执行此操作?

在游戏的API中没有一种方法可以处理
未来的
s。您可以包装Play的缓存API来处理
orElse
情况,其中它返回
未来的
。一般而言:

object FutureCache {

    def getOrElse[A](key: String, expiration: Int)(orElse: => Future[A])
      (implicit app: Application, ct: ClassTag[A], ec: ExecutionContext): Future[A] = {
        Cache.getAs[A](key).map(Future.successful).getOrElse {
            val value = orElse
            value onSuccess { case result => Cache.set(key, result, expiration) }
            value
        }
    }

}
用法:

FutureCache.getOrElse[JsValue]("gravatar-for-$userId", 3600) {
  WS.url("gravatar.com/email=$email").get().map(_.json)
}

您还可以为
getOrElse
创建一个重载,该重载使用
持续时间

您可以使用Promise[JsValue],类似于:

val userGravatar: Future[JsValue] = RemoteGravatarService.get(user.id, user.email)

object RemoveGravatarService {
  def get(userId: String, email: String): Future[JsValue] = {
    Cache.getOrElse("gravatar-for-$userId", 1.hour) {
      Promise[JsValue].completeWith(WS.url("gravatar.com/email=$email").get().map(_.json)
    }.future
  }
}

任何类型,但是让我们假设
JsValue
(因为它是可序列化的)。更新了带有类型注释的示例。这里重要的一点是,如果值已在缓存中就绪,我希望缓存以
Future.successful(previousJsonResult)
响应。您可以使用spray cache