如何在Scala中比较多个未来对象的成功

如何在Scala中比较多个未来对象的成功,scala,Scala,下面的代码使用print语句模拟在线购物。我使用Future来模拟一个场景,在这个场景中,我同时将多个项目添加到购物篮中(我将添加购物篮中的每个偶数项目)。我希望在最后,代码打印出有多少项被添加到篮子中 我创建了5个未来对象(所以我希望结果是5个) 我把每个未来都存储在一个列表中 我使用for循环来等待每个未来的完成 我希望在所有期货交易完成后,我选择他们的 Success对象并整理它们的值(添加它们)。这就是部分 我无法编码 import scala.concurrent._ import s

下面的代码使用print语句模拟在线购物。我使用Future来模拟一个场景,在这个场景中,我同时将多个项目添加到购物篮中(我将添加购物篮中的每个偶数项目)。我希望在最后,代码打印出有多少项被添加到篮子中

  • 我创建了5个未来对象(所以我希望结果是5个)
  • 我把每个未来都存储在一个列表中
  • 我使用for循环来等待每个未来的完成
  • 我希望在所有期货交易完成后,我选择他们的 Success对象并整理它们的值(添加它们)。这就是部分 我无法编码

    import scala.concurrent._
    import scala.concurrent.ExecutionContext.Implicits.global
    import scala.util.{Failure,Success}
    
    
    object ConcurrencyExample extends App {
    
      //simulation of backend process of adding an object in basket
      def addToBaskset(id:Int): Future[Int] = {
        Future {
          println("adding item "+id+" to shopping basket")
          Thread.sleep(10) //simulate backend process delay
          println("Item "+ id +" added")
          1 //simulate the no. of items in basket
        }
      }
    
      //simulate shopping. Pick even numbers and add them to baskset
      def simulateShopping(count:Int):List[Future[Int]] = {
        def go(c:Int, l:List[Future[Int]]):List[Future[Int]] = {
          println("looking at more items in inventory ")
          if(c == 0) l else
          if (c % 2 == 0)
          {
            Thread.sleep(10)
            go(c-1,addToBaskset(c)::l)
          }
          else {
            Thread.sleep(10)
            go(c-1,l)
          }
        }
        go(10,List())
      }
    
    
      val time = System.currentTimeMillis()
      val shoppingList: List[Future[Int]] = List()
    
      println("start shopping...")
      //simulate shopping of 10 items. Even values will be added to basket using Future. Return list of Future created
      val futures:List[Future[Int]] = simulateShopping(10)
    
      //wait for each item in list to finish. Its results will be collected in a new list called 'result'
      val result = for (i<- futures) yield i //we will get Success(1), 5 times
    
      println("finished shopping. result: " +result)
    
      **//how to I get a single integer value which is sum of all Success values?**
    //result seem to be a  List of Success() (not Future), so I tried using foldLeft or map but the code doesn't compile if I use them. I keep getting error for Unit value.
    
    
    }
    
    进程已完成,退出代码为0

    下面的代码似乎可以工作,但当打印显示结果元素成功时,为什么我必须将其作为Future[Int]来处理(1)


    您可以使用
    Future.sequence
    List[Future[Int]]
    转到
    Future[List[Int]]
    ,然后调用
    sum
    查看已添加的所有项目:

    val result: Int = Await.result(Future.sequence(futures).map(_.sum), 5 seconds)
    
    请注意,
    Await.result
    仅用于在未完成所有后续操作的情况下,测试不会过早终止

    当 打印显示他们成功了(1)


    因为
    Future[T].value
    返回一个
    选项[Try[T]
    ,其中
    Try
    可以是
    Success
    Failure
    。但它只会在未来完成时返回一个值。我根本不会使用
    .value

    您可以使用
    Future.sequence
    列表[Future[Int]]
    转换为
    未来[List[Int]]
    ,然后调用
    sum
    查看所有项目是否已添加:

    val result: Int = Await.result(Future.sequence(futures).map(_.sum), 5 seconds)
    
    Future.foldLeft(futures)(0)(_ + _).foreach(result => "finished shopping. result: " +result)
    
    请注意,
    Await.result
    仅用于在未完成所有后续操作的情况下,测试不会过早终止

    当 打印显示他们成功了(1)


    因为
    Future[T].value
    返回一个
    选项[Try[T]
    ,其中
    Try
    可以是
    Success
    Failure
    。但它只会在未来完成时返回一个值。我根本不会使用
    .value

    嗨,我不需要长度,只需要成功返回值的总和。我用一种行之有效的方法编辑了我的问题,但我不明白为什么当印刷品显示我有一份成功列表时,我得到了一份未来[Int]的列表(1)@ManuChadha我最初写的
    sum
    ,但不确定这是否是你想要的。我已经编辑了答案。@ManuChadha Youre for construction将生成一个
    Seq[Future[Int]
    ,类似于我使用
    Future.sequence的答案。但就目前看来,你实际上并不是在等待未来的完成。调用
    Future[T].get
    绝对不是推荐的方法。对于(i@ManuChadha不,它不是。它相当于调用
    result.map(identity)
    。没有隐含的等待完成。您好,我不需要长度,而是成功返回值的总和。我用一种有效的方法编辑了我的问题,但我不明白为什么当打印显示我有一个成功列表(1)时,我会得到一个未来[Int]列表@ManuChadha我最初写的是
    sum
    ,但不确定这是否是你想要的。我已经编辑了答案。@ManuChadha你的理解将产生一个
    Seq[Future[Int]]
    ,与我使用
    Future.sequence
    的回答类似。但从目前的情况看,您实际上并不是在等待未来的完成。调用
    Future[T].get
    绝对不是推荐的方法。对于(i@ManuChadha不,它不是。它相当于调用
    result.map(identity)
    。没有隐含的等待完成。
    Future.foldLeft(futures)(0)(_ + _).foreach(result => "finished shopping. result: " +result)