2017-04-25 4 views
0

내가 수행하는 서비스 호출을 기반으로 Int의 List를 반환하는 간단한 메서드를 작성했습니다.미래가 끝나면 값을 반환하는 방법은 무엇입니까?

내 문제는 ... 서비스 요청 메신저 결정이 어떤 가치의 미래를 반환, 그래서 내가 onComplete를을하고 나는 미래의 완료에 싶지만, onComplete를 단위를 반환 무엇을 반환 할 생각이다

이것이 내가 일하기를 원했던 방식입니다 :

def getListOfInts(str: String): List[Int] = { 
    myDaoService.findSomethingInDb(str).onComplete { 
     case Success(res) => 
     res.map(line => line.amount.toInt*100).distinct.filter(num => num != 0).toList 
     case Failure(exception) => logger.error(s"finding in db has failed with exeption: ", exception) 
    } 
    } 

미래가 완성 될 때 원하는 가치를 되돌려 놓는 올바른 방법은 무엇입니까?

는 내가 알고있는 보통의 map/flatmap하지만 ... 그것은 미래에 싸여 나는 내 방법은 실제 값이 아니라 값의 미래를 반환 할

덕분에 계속됩니다!

+0

스칼라 - 비동기 찾고있는 콜백 onFailure 있습니다 https://github.com/scala/async – sheunis

답변

2

Await.result으로가는 것이 좋습니다. 그러나 권장하지 않습니다.

import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.duration._ 
import scala.concurrent.Await 

def getListOfInts(str: String): List[Int] = { 
    Await.result(myDaoService.findSomethingInDb(str), 10 seconds).map(line => line.amount.toInt*100).distinct.filter(num => num != 0).toList 
} 

위의 방법가 될 때까지 권장되지 않으며, 당신은 결과에 대한 실행 대기 (블록)의 스레드를 만들고 싶어하지 않는 한. 위의 코드는 확장되지 않습니다.

권장되는 방법은 미래 (사용지도를하고 필요한 결과로 데이터베이스 호출의 출력 형식을 변환하는 flatmap) 구성하는 것입니다

def getListOfInts(str: String): Future[List[Int]] = 
myDaoService.findSomethingInDb(str).map { res => 
    res.map(line => line.amount.toInt*100).distinct.filter(num => num != 0).toList 
} 

권장 방법 다음 마지막을 얻기 위해 대기하고 최종 변환 결과.

+1

당신이 오직해야 테스트 코드 – sheunis

+0

에서 Await.result()를 사용하십시오.이 대답을 수락 할 수 있습니다. 비동기 API를 사용하는 동기화 메서드가 있으므로 결과 (실제로 권장되지 않음) 또는 전체 코드 비동기 (선물을 차례로 반환)를 기다려야합니다. –

+0

@sheunis 가끔은 우리 손에 달려 있습니다. 예를 들어 두 개의 라이브러리가있는 경우 하나는 비동기이고 다른 하나는 동기화 된 경우입니다. 따라서 Await을 사용해야한다. (적어도 Awit은 기다리지 않고 스레드의 진행을 방해한다.) 또는 sync (또는 async) 라이브러리를 버려야한다. 동기화 라이브러리 비동기 (때로는 불가능). –