回答
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
def f(x:String) = Future { x }
val functions = Seq(
() => f("a"),
() => f("b"),
() => f(""),
() => f("d"),
() => f("e"))
functions.takeWhile(x => Await.result(x(), 5 seconds) != "")
這會給你
res0: Seq[() => scala.concurrent.Future[String]] = List(<function0>, <function0>)
蔭不知道是否有另一種方法但爲了我的理解,如果你想根據前面的未來的結果來決定,你需要等待。
編輯: 這是一個遞歸方法。但在我看來,與迭代器的人是好的。
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
def f(x:String) = Future { x }
val functions = Seq(
() => f("a"),
() => f("b"),
() => f(""),
() => f("d"),
() => f("e"))
check(functions, 0)
def check(list:Seq[() => Future[String]], pos:Int):String = {
if(list.size <= pos) return ""
val res = Await.result(list(pos)(), 5 seconds)
if(condition(res)) {
res
}
else check(list, pos+1)
}
def condition(c:String):Boolean = if(c == "d") true else false
它的尾遞歸,因此你的堆棧不會溢出那麼容易。
有沒有辦法等待? –
如果您依賴於以前的結果,則不適用。如果你想篩選和刪除不符合條件的條目,那麼是的。 – sascha10000
好的,但在這個解決方案完成時,我得到了功能,而不是價值 –
您可以使用iterator
和flatMap
。下面是一個簡化的例子:
import scala.concurrent.Await
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
val functions: Seq[() => Future[Int]] = Seq(
() => Future(1),
() => Future(2),
() => Future(3),
() => Future(4),
() => Future(5)
)
def checkResult(result: Int): Boolean = result > 3
functions.iterator.flatMap { func =>
val result = Await.result(func(), 5.seconds)
if (checkResult(result)) Some(result) else None
}.next()
該代碼將返回。
更新:
如果你只關心正確的結果並不在意所有期貨是否得到執行,你可以用fallBackTo
把它們連:
import scala.util._
functions.tail.foldLeft[Future[Int]](functions.head().filter(checkResult)) {
case (result, function) =>
result.fallbackTo(function().filter(checkResult))
}.onComplete {
case Success(result) => s"Got one: $result"
case Failure(exception) => s"Damn! Got NO result due to: $exception"
}
這將使你0123¾將與Success(4)
完成與我的例子謂詞x > 3
。
更新2
當我發現自己有一些額外的時間,我冒昧地在其他的答案(尤其是Alexander Azarov)的一些意見和建議以貸款模式相結合方法:
import scala.annotation.tailrec
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
val functions: Seq[() => Future[Int]] = Seq(
() => Future(1),
() => Future(2),
() => Future(3),
() => Future(4),
() => Future(5)
)
def checkResult(result: Int): Boolean = result > 5
def withFirstValidResult[A, B](futureFuncs: Seq[() => Future[A]], predicate: A => Boolean, defaultValue: A)(op: (A) => B): Future[B] = {
@tailrec
@inline def find(remaining: Iterator[Future[A]]): Future[A] = {
if (remaining.hasNext) {
remaining.next().filter(predicate).recoverWith {
case _ =>
find(remaining)
}
} else {
Future.successful {
println(s"No valid result found, falling back to default: $defaultValue")
defaultValue
}
}
}
find(futureFuncs.iterator.map(_())).map(op)
}
你現在可以使用這個函數來處理你想要的任何類型的期貨,並提供一個應該用第一個有效結果或者defaultValue執行的操作(雖然恕我直言,如果沒有有效的結果我寧願一個Failure
適當的錯誤處理我自己):
withFirstValidResult(functions.iterator, checkResult, 0) { result =>
println(s"Got a valid result: $result")
}.onFailure {
case ex =>
println(s"Got NO valid result: $ex")
}
作爲一個額外的小費,如果你想加速功能,可以迭代懶洋洋地在與futureFuncs.iterator.buffered
一次評估兩種功能。這樣,當一個未來的結果正在被評估時,迭代器將自動開始下一個未來。
有沒有辦法等待? –
謝謝!,任何想法,爲什麼我得到Future.filter謂詞不滿意? –
[NoSuchElementException:Future.filter謂詞不滿意]] –
def firstF[A](seq: Seq[() => Future[A]], predicate: A => Boolean): Future[A] =
seq.head().filter(predicate).recoverWith {
case _ => firstF[A](seq.tail, predicate)
}
方法firstF
將返回符合指定條件的第一Future
。如果輸入Future
均不匹配,則結果Future
將爲Failure
。爲了否則返回一些默認值,你根本就
firstF(seq, predicate).recover { case _ => default }
注1這裏的代碼演示了基本原則和計劃內或計劃外的異常之間沒有區別。
注2此代碼不是尾遞歸。
在這個解決方案中我得到了NoSuchElementException:空列表頭部 –
@ Ben.om如果沒有元素匹配謂詞,你會得到這個異常。但是你沒有在你的問題中指定這個場景。 –
好吧,它可以是任何功能沒有太多,所以在這種情況下,我需要返回瑕疵值 –
- 1. 斯卡拉 - 等待所有期貨在期限內完成
- 2. 期貨在斯卡拉
- 3. 映射斯卡拉期貨
- 4. 斯卡拉,執行期貨
- 5. playframework斯卡拉如何等待asyncronousity
- 6. 斯卡拉:如何等待未來
- 7. 卡住與斯卡拉期貨
- 8. 如何拉平期貨的一個列表,斯卡拉
- 9. 等待期貨
- 10. 由斯卡拉撰寫期貨異步
- 11. 玩/斯卡拉/期貨:鏈接請求
- 12. 帶期貨的斯卡拉風格
- 13. 鏈斯卡拉期貨返回類型
- 14. 斯卡拉 - 期貨不運行
- 15. 斯卡拉擺脫嵌套期貨
- 16. 斯卡拉期貨對於理解
- 17. 斯卡拉期貨返回的價值
- 18. 斯卡拉期貨基礎知識
- 19. 在斯卡拉期貨迷路
- 20. 結合期貨(Twitter)和斯卡拉
- 21. 斯卡拉期貨和多線程
- 22. 斯卡拉 - 鏈接期貨嘗試塊?
- 23. 斯卡拉異步和等待限制
- 24. 斯卡拉無盡的等待
- 25. 如何處理斯卡拉期貨中的例外情況?
- 26. Akka期貨清單 - 如何等待期貨清單完成?
- 27. 如何等待演員在斯卡拉停下來
- 28. 等待「遞歸」期貨階
- 29. 等待多個期貨的回調
- 30. 在斯卡拉 - 如何獲得星期幾?
不完全是主題,但我強烈建議scalaz任務超過期貨。我發現期貨有一些奇怪的行爲,比如IO被推遲到執行結束。 – Marcin
注意:OP刪除了他/她的問題。 –