2015-09-28 143 views
0

下面的方法,我有利用異步庫:斯卡拉方法返回一個Future

def myMethod(param: Long, isTru: Boolean): Future[Option[MyType]] = async { 

    if (isTru) { 
    val promise = Promise[Option[MyType]] 

    val myFuture = doSomething(param) 

    myFuture.onComplete { 
     case Success(succ) => { 
     promise.success(Some(MyType(param, succ))) 
     } 
     case Failure(fail) => promise.failure(fail) 
    } 

    promise.future // fails here 
    } 
    else { 
    None 
    } 
} 

它無法編譯與錯誤:

[error] found: scala.concurrent.Future[Option[MyType]] 
[error] required: Option[MyType] 

我不明白?

回答

6

你可以像這樣做,沒有承諾和異步

def myMethod(param: Long, isTru: Boolean): Future[Option[MyType]] = { 

    if (isTru) { 
     doSomething(param).map(res => Some(MyType(param, res))) 
    } 
    else { 
     Future.successful(None) 
    } 
    } 

承諾未來ES實際上很少使用

,或者如果你想異步使用像這樣做:

def myMethod(param: Long, isTru: Boolean): Future[Option[MyType]] = async { 

    if (isTru) { 
     val myFuture = doSomething(param) 
     val myResult = await(myFuture) 

     Some(MyType(param, myResult)) 
    } 
    else { 
     None 
    } 
    } 

使用異步塊的整點是,你從它返回的是某種類型的你想要的(也許不是一個未來),然後它被包裹在一個。所以如果你需要Option[MyType]歸還它,它會被包裹在一個未來,讓你預計Future[Option[MyType]]。使async有用的是await()函數,它將Future[T]更改爲T,您可以正常使用它,而無需映射和其他類似事情,它有時比嵌套很多flatMaps更具可讀性。

(可選)如果您只是將promise.future換成await()這樣的await(promise.future),那麼您的代碼應該可以正常工作,但這種解決方案對我而言非常難看。

+0

問題是我的await調用在yield塊中,我不能在這種情況下使用await。我上面展示的例子只是一個簡化版本! – sparkr

+1

好,然後顯示不顯示,也許我們可以找出一些東西。等待當然有其侷限性。 –

+0

它是 - http://stackoverflow.com/questions/32823943/scala-synchronising-asynchronous-calls-with-future – sparkr

0

的兩個分支「如果」語句返回值應該是選項[MyType的],如果使用異步{...}或將來的[選項[MyType的],那麼你就需要異步

+0

也行不通! – sparkr

1

Option類型不是類型Future,注意if-else表達,

if() {... 
    promise.future // fails here 
} 
else { 
    None 
}