回答
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. playframework斯卡拉如何等待asyncronousity
- 4. 如何拉平期货的一个列表,斯卡拉
- 5. 等待期货
- 6. 由斯卡拉撰写期货异步
- 7. 斯卡拉 - 期货不运行
- 8. 斯卡拉期货和多线程
- 9. 玩/斯卡拉/期货:链接请求
- 10. 链斯卡拉期货返回类型
- 11. 带期货的斯卡拉风格
- 12. 斯卡拉期货对于理解
- 13. 斯卡拉无尽的等待
- 14. 斯卡拉异步和等待限制
- 15. 如何处理斯卡拉期货中的例外情况?
- 16. 如何等待演员在斯卡拉停下来
- 17. 在浮油和斯卡拉特拉期货中工作
- 18. 等待斯卡拉未来完成并继续下一个
- 19. 订货与代数类型斯卡拉
- 20. 斯卡拉测试用火和忘记期货
- 21. 玩2.1斯卡拉连锁多期货和承诺
- 22. 斯卡拉演员而不是爪哇期货
- 23. 斯卡拉:合并排序利用期货超时
- 24. 斯卡拉期货尽管使用awaitAll不输出到屏幕?
- 25. 斯卡拉混合列表和期货的理解中
- 26. 如何从斯卡拉(卡斯巴)
- 27. 如何等待几个对象
- 28. 斯卡拉电梯 - 运行系统命令,并等待完成
- 29. 斯卡拉顺序发布使用无需等待理解
- 30. 斯卡拉等待未来的列表执行
不完全是主题,但我强烈建议scalaz任务超过期货。我发现期货有一些奇怪的行为,比如IO被推迟到执行结束。 – Marcin
注意:OP删除了他/她的问题。 –