[英]Dependent futures
開始玩Scala期貨,我陷入了依賴期貨的困境。
我們來舉個例子。 我搜索地點並獲得Future[Seq[Place]]
。 對於每個地方,我搜索最近的地鐵站(該服務重新開始Future[List[Station]]
)。
我會寫這個:
Place.get()
.map { places =>
places.map { place =>
Station.closestFrom(place).map { stations =>
SearchResult(place, stations)
}
}
}
那件事會讓我得到一個Future[Seq[Future[SearchResult]]]
......這不是我所期待的。
我錯過了什么來獲得Future[Seq[SearchResult]]
?
謝謝大家,
阿爾班
您在解決方案中缺少兩個Future
概念: flatMap
和Future.sequence
解釋每個:
flatMap
就像map
一樣,除了從future.map(A => B)
給它一個函數,你從future.flatMap(A => Future[B])
給它一個函數future.flatMap(A => Future[B])
。 這樣你就可以將期貨連在一起了。
Future.sequence
是一個輔助函數,它將期貨列表與列表的未來結合起來: Seq[Future[A]] => Future[Seq[A]]
使用Future
API的這兩個功能,我們可以將您的答案更改為:
Place.get().flatMap { places =>
Future.sequence(places.map { place =>
Station.closestFrom(place).map { stations =>
SearchResult(place, stations)
}
})
}
使用for-understand進行使用期望通常更容易,而不是直接映射/ flatMap。 在你的情況下,它應該是這樣的:
for {places <- Place.get()
searchResults <- Future.traverse(places)(place => for (stations <- Station.closestFrom(place))
yield SearchResult(place,stations)
)
} yield searchResults
Future
是一個單子,它為您提供了幾種連接您的運營方式。
f : A => B
到框內的myfuture : Future[A]
,確實是map
是獲得Future[B]
。 但是在目前情況下, Station.closestFrom
a沒有給你一個List[Stattion]
而是一個Future[List[Station]]
。 h : A => Future[B]
或鏈接其中幾個(這里是Places.get
和Station.closestFrom
), flatMap
就是你要走的路。 將h
應用於Future[A]
為您提供Future[B]
。 h : A => Future[B]
到類似places : Seq[A]
的集合places : Seq[A]
,你應該使用Future.traverse : Seq[A] => (A => Future[B]) => Future[Seq[B]]
。 此外,Scala的for-compresention只是flatMap / map的語法糖,所以不用直接使用它們編寫復雜的代碼,你可以使用干凈清晰的for循環。 循環:
for { variable1 <- f1
variable2 <- f2
} yield expression
相當於(沒有優化):
f1.flatMap( variable1 => f2.map(variable2 => expression))
不要猶豫使用for-understanding,它確實有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.