2014-12-01 25 views
0

林有一個問題從未來[JsValue]地圖和Flatmap未來[JsValue]

我試着地圖和Flatmap但我猜即時通訊做財產以後錯...

我有這樣的提取字符串值方法返回未來[JsValue]

val chunk: Future[JsValue] = BusinessLogic.Methods.getJsonValue(url) 

如果我是地圖我得到一個未來[字符串]

val next: Future[String] = (chunk.map(_.\("paging").\("next").as[String])) 

如果我使用平面地圖,我得到類型不匹配

val next = chunk.flatMap(x=>x.\("paging").\("next").as[String]) 

會有什麼正確的方法來提取價值?

感謝

+0

你是什麼意思提取的價值?如果你想打開未來,你必須阻止(並根據你想做什麼,這可能是一個壞主意)。 'map'將未來的匿名函數的結果封裝起來,'flatMap'代替將來需要包裝結果,在這兩種情況下,返回類型都是'Future [T]'。 – 2014-12-01 21:01:14

+0

我必須從未來獲取字符串值,以便將它傳遞給另一個字符串的方法 – MIkCode 2014-12-01 21:38:38

+3

'next.map(otherFunctionThatTakesAString)' – Ryan 2014-12-01 22:04:26

回答

0

http://docs.scala-lang.org/overviews/core/futures.html

從公報的教程,關於地圖:

一種基本的組合子是地圖,其中,由於未來和 映射函數的值未來,產生一個新的未來 ,一旦原始未來成功完成, 就完成了映射值。

關於平面地圖。

flatMap方法採用一個函數,該函數將該值映射到新的未來g,然後返回g完成後完成的未來。

因此,在您的情況下,因爲您只是想將響應轉換爲其他值,您需要一個映射函數,它將您的未來結果映射到String。

val next: Future[String] = (chunk.map(_.\("paging").\("next").as[String])) 

這裏的下一個值是從塊或者將塊js值映射到String的結果。

如果你將有一些額外的異步計算,像

def calculations: (x: String): Future[Int] = ... 

val next: Future[Int] = chunk.flatMap(js=> { 
    val x = js.\("paging").\("next").as[String] 
    calculations(x) 
}) 

您將需要使用flatMap,在一個組合兩個相關的異步期貨。下一個值是計算函數的結果,應用於從塊返回的結果。

+0

我嘗試以這種方式嘗試,但我去錯誤 scala遞歸調用不在尾部位置 – MIkCode 2014-12-02 17:54:41

+0

你能更具體一些嗎?你嘗試過哪一個?你確定遞歸調用是指這個映射函數,而不是別的? – mavarazy 2014-12-03 05:38:21

+0

這是遞歸方法 def inner(url:String,commentList:Future [List [JsValue]]):Future [List [JsValue]] = { val chunk:Future [JsValue] = BusinessLogic.Methods.getJsonValue(url ) VAL jsList:(_ \( 「數據」)未來[列表[JsValue] = chunk.map爲[列表[JsValue]]) chunk.flatMap(X => { 下VAL。 (下一個!= null) inner(next,commentList.flatMap(l => jsList.map(l2 => l) ++ l2))) else commentList.flatMap(l => jsList.map(l2 => l ++ l2)) }) } inner(url,Future.successful(Nil)) } – MIkCode 2014-12-03 18:26:37

0

如果你想打開你的未來,你必須阻止。這是一個非常糟糕的主意,如果可能的話應該避免!

def nextFunction(s:String):Unit = ??? 
val chunk: Future[JsValue] = BusinessLogic.Methods.getJsonValue(url) 
val next: String = Await.result(chunk, 1.second) 
nextFunction(next) 

如上所述,這是一個壞主意!更好的解決方案是:

def nextFunction(s:String):Unit = ??? 
val chunk: Future[JsValue] = BusinessLogic.Methods.getJsonValue(url) 
chunk.foreach(nextFunction) 

這基本上調用nextFunction的值,只要它是可用的,我們永遠不會阻止。