2016-07-09 1 views
2

두 함수가 있습니다. 하나는 Future[Thing Or Exception]을 반환하고 다른 하나는 Future[Boolean을 반환합니다. 모두 호출하고 Future[Thing Or Exception]을 반환하는 함수가 필요합니다. 부울 함수가 false를 반환하면 예외를 반환하고 그렇지 않으면 다른 함수를 반환합니다.서로 다른 유형의 여러 선물에서 Scala Future를 작성하는 데 문제가 있습니다.

나는 다음과 같이 코드를 가지고있다. 그러나 나는 캐스트와 b)를 싫어한다. 결국 "boolean gets true"경로를 실행할 때 "Promise$DefaultPromise cannot be cast to org.scalatic.Or"의 결과로 Await.result이 나오면이 오류가 발생한다.

def thingFuture: Future[Thing Or Exception] 
def boolFuture: Future[Boolean] 

def combineFutures: Future[Thing Or Exception] = { 
    val result = boolFuture.map {x => 
    x match { 
     case true => thingFuture 
     case false => Exception 
    } 
    } 
    // without the cast compiler says result is of type Future[Object] 
    result.asInstanceOf[Future[Thing Or Exception]] 
} 

나는이 시도했다 그러나 사람이 어떻게 다른 반환 유형이 선물을 구성하는 방법을 말해 줄래 성공 경로

def combineFutures: Future[Thing Or Exception] = { 
    val result = boolFuture.map {x => 
    x match { 
     case true => thingFuture.map { y => 
     y match { 
      case Good(thing) => thing 
      case Bad(exception) => exception 
     } 
     case false => Exception 
    } 
    } 
} 

에 같은 약속 오류를 얻는다? 감사!

답변

2

예외가 발생한 경우를 대비하여 실패한 상태로 모든 미래를 완료 할 수 있으므로 "행복한 경로"에서 thingFuture를 반환하고 부울 값이 false 인 경우 예외를 throw 할 수 있습니다. 기본 예외가있는 Future.failed을 반환합니다.

val result = boolFuture.flatMap {x => 
    x match { 
    case true => thingFuture 
    case false => throw new Exception("whatever") 
    } 
} 

주 대신 mapflatMap. 우리는 하나의 미래의 기본 가치를 또 다른 미래로 매핑하기 때문에 map이라는 간단한 코드를 사용하여 Future[Future[Thing]]으로 끝낼 것입니다.

또한 예외를 throw하는 대신 Future.failed(throw new Exception("whatever"))을 반환 할 수 있으며 결과는 동일 할 것입니다. 두 경우 모두 실패한 미래를 보게됩니다.

편집 : 방금 Or은 결코 사용하지 못했던 확장 성에서 비롯되었지만 철학은 동일하게 유지됩니다. Future[ThingOrException]을 사용하려면 부울의 미래와 ThingOrException의 미래를 flatMap해야합니다. 만약 당신이 flatMap Future를 필요로하는 상황에서 스스로를 찾았지 만 case 절 중 하나가 보통 값을 반환하면 (예 : true return Future[Thing]의 경우 false 반환의 경우 단지 Exception) 일반적인 값을 감쌀 수 있습니다 미래로. 이 방법은 모든 지점 미래를 반환하고 flatMap 제대로 작동합니다. 예를 들어 :

val someOtherFuture = Future(43) 
val someOrdinaryValue = 44 

Future(someInteger).flatMap { 
    case 42 => someOtherFuture 
    case _ => Future(someOrdinaryValue) 
} 

런타임 기계에 대한 물건을 조금 단순화하기 위해, 당신은 또한 어떤 배경 계산이 시작되지 않은 경우 Future.successful(someOrdinaryValue)를 작성할 수 있습니다.

1

Scalatic 설명서에서 알 수있는 한 Good(Right) 또는 Bad(Left)에 의해 Right Or Left의 인스턴스를 얻을 수 있습니다. 잠재적 같을 수있는 조성물을 의미

:

boolFuture.flatMap(b => if (b) thingFuture else Future.successful(Bad(new Exception()))) 

종류는 Future[Or[Thing, Exception]]

을 통일해야
관련 문제