【问题标题】:handle multiple Future in Scala在 Scala 中处理多个 Future
【发布时间】:2017-05-14 05:17:52
【问题描述】:

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

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

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

【问题讨论】:

  • 你知道你必须事先处理多少个期货吗?
  • 不,但我很高兴假设尺寸有限。但是,我希望解决方案使用 List[Future] 而不是像 f1, f2 这样的单个 val
  • 类似:Future.sequence(futures2.map(_.recover{case NonFatal(e) => 0})).map(_.sum)...
  • 是的,它是重复的。感谢您的参考。我看不到将此问题标记为重复的链接。

标签: scala


【解决方案1】:

您需要了解的一件事是...避免尝试从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 中“获取”一个值,我添加了一些关于 Promise 在 Scala 中的内容。

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

如果您看到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 值的承诺...仅此而已。

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

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

所以...基本上 PromiseFuture 包裹在其中。而那个"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 中运行......你无法在你的时间线中“获得”它们的“价值”,除非你努力使你的时间线与进程的时间线本身保持一致.

【讨论】:

  • 如果我想从异步进程中“获取”一些价值,我应该使用 Promise 吗?
猜你喜欢
  • 1970-01-01
  • 2017-02-27
  • 2016-01-23
  • 2015-12-28
  • 1970-01-01
  • 1970-01-01
  • 2018-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多