在Scala中处理多个Future

时间:2016-12-29 21:06:43

标签: scala

我想创建一个Future列表,每个列表都可以通过或失败,并整理成功Future的结果。我怎么能这样做?

val futures2:List[Future[Int]] = List(Future{1}, Future{2},Future{throw new Exception("error")})

问题 1)我想等待每个未来完成 2)我想从每个成功的未来收集返回值的总和,并忽略失败的那些(所以我应该得到3)。

1 个答案:

答案 0 :(得分:3)

您需要了解的一件事是......避免尝试"得到"来自FutureFutures

的值

您可以继续在Futuristic土地上开展工作。

val futureList = List(
  Future(1),
  Future(2),
  Future(throw new Exception("error"))
)

// addd 1 to futures
// map will propagate errors to transformed futures
// only successful futures will result in +1, rest will stay with errors
val tranformedFutureList = futureList
  .map(future => future.map(i => i + 1))

// print values of futures
// simimlar to map... for each will work only with successful futures
val unitFutureList = futureList
  .map(future => future.foreach(i => println(i)))

// now lets give you sum of your "future" values
val sumFuture = futureList
  .foldLeft(Future(0))((facc, f) => f.onComplete({
    case Success(i) => facc.map(acc => acc + i)
    case Failure(ex) => facc
  })

自从OP(@Manu Chanda)询问"得到"来自Promise的值,我正在添加一些关于Scala中Promise的内容。

所以...首先让我们谈谈如何考虑Future中的Scala

如果您看到Future[Int],请尝试将其视为an ongoing computation,这是"应该生成" Int。现在计算可以successfully complete并产生Success[Int]throw an exception并产生Failure[Throwable]。因此,您可以看到onCompleterecoverWithonFailure等功能,这些功能似乎在讨论计算。

val intFuture = Future {
  // all this inside Future {} is going to run in some other thread
  val i = 5;
  val j = i + 10;
  val k = j / 5;
  k
}

现在......什么是Promise

嗯......正如名称所示...... Promise[Int]Int价值的承诺......仅此而已。

就像父母向孩子承诺某个玩具一样。请注意,在这种情况下...父母不一定开始着手获得那个玩具,他们只是答应他们会这样做。

要完成承诺......他们首先必须开始努力完成它......进入市场......从商店购买......回到家里。或者......有时......他们很忙所以...他们会要求其他人带上那个玩具并继续做他们的工作......其他人会试图把那个玩具带给父母(他可能没有买到它)然后他们会用任何结果完成承诺他们从他那里得到了。

所以...基本上Promise包裹Future内部。那"wrapped" Future"价值"可以视为Promise的值。

所以...

println("Well... The program wants an 'Int' toy")

// we "promised" our program that we will give it that int "toy"
val intPromise = Promise[Int]()

// now we can just move on with or life
println("Well... We just promised an 'Int' toy")

// while the program can make plans with how will it play with that "future toy"

val intFuture = intPromise.future
val plusOneIntFuture = intFuture.map(i => i + 1)

plusOneIntFuture.onComplete({
  case Success(i) => println("Wow... I got the toy and modified it to - " + i)
  case Failure(ex) => println("I did not get they toy")
})

// but since we at least want to try to complete our promise
println("Now... I suppose we need to get that 'Int' toy")
println("But... I am busy... I can not stop everything else for that toy")
println("ok... lets ask another thread to get that")

val getThatIntFuture = Future {
  println("Well... I am thread 2... trying to get the int")
  val i = 1
  println("Well... I am thread 2... lets just return this i = 1 thingy")
  i
}

// now lets complete our promise with whatever we will get from this other thread
getThatIntFuture.onComplete(intTry => intPromise.complete(intTry))

以上代码将导致以下输出

Well... The program wants an 'Int' toy
Well... We just promised an 'Int' toy
Now... I suppose we need to get that 'Int' toy
But... I am busy... I can not stop everything else for that toy
Well... I am thread 2... trying to get the int
Well... I am thread 2... lets just return this i = 1 thingy
Wow... I got the toy and modified it to - 2

Promise请不要帮助你"得到"来自Future的值。异步流程(或Scala中的Future)只是在另一个timeline中运行...你不能"得到"他们的价值"在您的时间线中,除非您将时间线与流程的时间线本身对齐。