Scala的未来是怎样的?

Scala的未来是怎样的?,scala,future,standard-library,Scala,Future,Standard Library,Scala未来标准API中有map/flatMap方法,也有recover/recoverWith方法 为什么没有带的收集器 collect方法的代码非常简单: def collect[S](pf:PartialFunction[T,S])(隐式执行器:ExecutionContext):Future[S]= 地图{ r=>pf.applyOrElse(r,(t:t)=>抛出新的NoSuchElementException(“Future.collect部分函数未定义在:“+t”) } col

Scala未来标准API中有
map
/
flatMap
方法,也有
recover
/
recoverWith
方法

为什么没有带的
收集器

collect
方法的代码非常简单:

def collect[S](pf:PartialFunction[T,S])(隐式执行器:ExecutionContext):Future[S]=
地图{
r=>pf.applyOrElse(r,(t:t)=>抛出新的NoSuchElementException(“Future.collect部分函数未定义在:“+t”)
}
collectWith
方法的代码很容易想象:

def collectWith[S](pf:PartialFunction[T,Future[S])(隐式执行器:ExecutionContext):Future[S]=
平面图{
r=>pf.applyOrElse(r,(t:t)=>抛出新的NoSuchElementException(“Future.collect部分函数未定义在:“+t”)
}
由于本文,我知道我可以轻松实现它并“扩展”未来的标准API:

我在我的项目中做到了这一点:

class richfourture[T](未来:未来[T]){
def collectionwith[S](pf:PartialFunction[T,Future[S])(隐式执行器:ExecutionContext):Future[S]=
future.flatMap{
r=>pf.applyOrElse(r,(t:t)=>抛出新的NoSuchElementException(“Future.collect部分函数未定义在:“+t”)
}
}
富有前途的特点{
隐式def enrichfourture[T](person:Future[T]):richfourture[T]=新的richfourture(person)
}
也许我对它的需求不足以在标准API中实现它

以下是我在Play2项目中需要此方法的原因:

def createCar(key:String,eligibleCars:List[Car]):Future[Car]={
def HandlerResponse:PartialFunction[WSResponse,Future[Car]={
案例响应:WSResponse if response.status==status.CREATED=>Future.successful(response.json.as[Car])
案例响应:WSResponse
如果response.status==status.BAD\u REQUEST&&response.json.as[Error]。Error==“不是好的”=>
createCar(钥匙、易识别卡、尾部)
}
//“carapClient.createCar”方法只返回WS-API调用的结果。
CarapClient.createCar(键,eligibleCars.head).collectWith(HandlerResponse)
}
如果没有我的
collectWith
方法,我不知道如何做到这一点

也许这不是做这种事情的正确方式?
你知道更好的方法吗


编辑:

对于
createCar
方法,我可能有一个更好的解决方案,它不需要
collectWith
方法:

def createCar(key:String,eligibleCars:List[Car]):Future[Car]={
为了{
mayCar:选项[Car]doCall(头部、尾部)
案例Nil=>Future.failed(新运行时异常)
}
}
朱尔斯

怎么样:

def createCar(key: String, eligibleCars: List[Car]): Future[Car] = {
  def handleResponse(response: WSResponse): Future[Car] = response.status match {
    case Status.Created => 
      Future.successful(response.json.as[Car])
    case Status.BAD_REQUEST if response.json.as[Error].error == "not_the_good_one" =>
      createCar(key, eligibleCars.tail)
    case _ =>
      // just fallback to a failed future rather than having a `collectWith`
      Future.failed(new NoSuchElementException("your error here"))
  }

  // using flatMap since `handleResponse` is now a regular function
  carApiClient.createCar(key, eligibleCars.head).flatMap(handleResponse)
}
两个变化:

  • handleResponse
    不再是部分功能。
    案例
    返回失败的未来,这基本上就是您在自定义
    collectWith
    实现中所做的
  • 使用
    flatMap
    而不是
    collectWith
    ,因为
    handleResponse
    现在适合该方法签名

编辑以获取额外信息

如果您确实需要支持
PartialFunction
方法,则始终可以通过调用部分函数上的
orElse
PartialFunction[a,Future[B]
转换为
函数[a,Future[B]
,例如

val handleResponsePF: PartialFunction[WSResponse, Future[Car]] = {
  case ....
}

val handleResponse: Function[WSResponse, Future[Car]] = handleResponsePF orElse {
  case _ => Future.failed(new NoSucheElementException("default case"))
}
这样做将允许您调整现有的分部函数以适应
flatMap
调用


(好的,从技术上讲,它已经做到了,但是你会抛出匹配错误,而不是你自己的自定义异常)

我发现你的flatMap解决方案非常好,因为lisible!感谢=)并感谢您提供有关将PartialFunction转换为函数的信息。我不知道这个把戏=)