[英]for-comprehension vs Future.sequence
我的機器上有4個核心。
而且我認為全面理解可以並行安排進度(不依賴於先前的結果..與flatMap相同):
val stuffResult: Future[String] = for {
stuff1 <- service1.doServiceStuff("service 1") // worker-5 (4+1)
stuff2 <- service1.doServiceStuff("service 2")
stuff3 <- service1.doServiceStuff("service 3")
stuff4 <- service1.doServiceStuff("service 4")
} yield (stuff1 + ", " + stuff2 + ", "+ stuff3 + ", " + stuff4)
哪里
class Service {
implicit val blockingExContext = scala.concurrent.ExecutionContext.fromExecutor(null: Executor)
def doServiceStuff(name:String): Future[String] = {
Future {
blocking {
println ( s"start ${name} on " + Thread.currentThread.getName)
Thread.sleep(5000)
"stuff_done"
}
}
}
}
但是我看到的是(每個步驟大約需要5秒鍾):
所有程序都在一個線程上運行,而不是使用現有的免費程序,並以最快的速度完成所有操作-只需約5秒。
但是如果我選擇:
val stuff1 = service1.doServiceStuff("service 1")
val stuff2 = service1.doServiceStuff("service 2")
val stuff3 = service1.doServiceStuff("service 3")
val stuff4 = service1.doServiceStuff("service 4")
Future.sequence(List(stuff1, stuff2, stuff3, stuff4)).map { list =>
list.foldLeft("") { (acc, x) => acc + " " + x }
}
..
全部在5秒內結束。
哪個pont理解能力會依次起作用? 可以?
它不能順序工作,它只能在創建Future
之前啟動(在您的前一個Future
flatMap
,這會發生),因此,如果要並行處理它們,則需要提前創建它們(以及通常的隱式ExecutionContext
)。
不過, 本教程可能解釋得更好(它使withFilter
變得復雜):
僅在usdQuote和chfQuote均完成后,購買期貨才完成–它取決於這兩個期貨的值,因此其自身的計算不能更早地開始。
上面的理解翻譯為:
val purchase = usdQuote flatMap { usd => chfQuote
.withFilter(chf => isProfitable(usd, chf))
.map(chf => connection.buy(amount, chf)) }
這比理解要難一點,但是我們對其進行分析以更好地理解flatMap操作。 flatMap操作將其自身的價值映射到其他未來。 一旦完成了這個不同的未來,就將以其價值完成最終的未來。 在我們的示例中,flatMap使用usdQuote期貨的價值將chfQuote的價值映射到第三個期貨中,該期貨發送了購買一定數量瑞士法郎的請求。 只有從地圖返回的第三個未來完成后,才能完成最終的未來購買。
您真正需要的只是諸如map2
之類的東西,而不是flatMap
類的東西,因為您不使用前一個Future
的返回值來創建新的Future
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.