2013-08-06 103 views
5

當使用Playframework,我有時會遇到這種情況:在Playframework中使用Scala Future?

def myFunction:Future[String] = { 
    // Do some stuff 
} 

myFunction.onComplete { 
    case Success(myString) => // Du Stuff 
    case Failure(error) => // Error handling 
} 

但作爲斯卡拉文檔指出,Future.onComplete返回單位。 當Action函數例如期望SimpleResult時,如何使用Playframework中的函數?處理期貨的最佳做法是什麼?

編輯:我應該補充說,我使用Play-2.2.x分支,爲Scala未來交易了Play Future。

+0

有趣的鏈接@flavian,謝謝。 –

回答

7

您可以使用Async

def index = Action{ 
    val myFunction:Future[Option[String]] = // 
    Async{ 
     myFunction.map{ 
     case Some(x) => Ok(x) 
     case None => InternalServerError 
     } 
    } 
} 

基本上你告訴播放:每當myFunction評價,將結果返回給用戶。這裏的訣竅是map上的Future內容而不是使用回調,這可以讓您對結果進行操作。

奇妙的是它仍然是異步的。在這種意義上,http請求線程評估索引不會被阻止。

關於它的一些文檔here

+0

你確定嗎?據我所知Async是一個包裝器,期望一個'Future [SimpleResult]'而onComplete'返回一個Unit。使這不編譯。我應該補充說我使用Play 2.2.0-M2,它已經通過Scala期貨交換了Play's Futures。 –

+0

編輯代碼,以前的道歉 – Jatin

1

播放(在2.1至少)增加了一個extend1方法可能對您有用:

def myFunction: Future[String] = ??? 

myFunction.extend1 { 
    case Redeemed(v) => s"Got result string: $v" 
    case Thrown(t) => s"Got throwable: ${t.getMessage}" 
} // : Future[String] 

它可能會更好,但是,有失敗的明確計算,例如使用(如Jatin所示),Eitherscalaz.\/

編輯:正如您所指出的,已在Play 2.2中棄用。這是微不足道的效仿其行爲與Future方法,例如:

myFunction.map(v => s"Got result string: $v").recover { 
    case t => s"Got throwable: ${t.getMessage}" 
} 

如果你想重新創建extend1語法,這將是簡單的添加相應的implicits。

+0

事實上,在'2.2'之前的版本中,我使用'.extend1',但簽名與'scala.concurrent.Future'不兼容。 –

+0

我編輯了我的答案,其中包含了這樣做的一種方法。例如,您也可以創建一個新的'Promise',在'onComplete'塊中輸入它,並返回它的'Future'。 – Hugh

相關問題