当前位置: 首页 > 知识库问答 >
问题:

如何在Scala中整理多个Future对象的成功

陶英纵
2023-03-14

以下代码通过使用print语句模拟在线购物。我正在使用Future来模拟一个场景,在该场景中,我同时将多个商品添加到购物篮中(我正在添加购物篮中的每个偶数商品)。我希望最后,代码会打印有多少商品已添加到购物篮中。

>

  • 我创建了 5 个 Future 对象(因此我期望结果为 5 个)
  • 我将每个未来存储在一个列表中。
  • 我使用for循环来等待每个未来的完成
  • 我希望在所有期货执行之后,我选择他们的成功对象并整理他们的值(添加他们)。这是我无法编码的部分。

    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.
    
    
    }
    

    结果

    start shopping...
    looking at more items in inventory 
    looking at more items in inventory 
    adding item 10 to shopping basket
    Item 10 added
    looking at more items in inventory 
    adding item 8 to shopping basket
    looking at more items in inventory 
    Item 8 added
    looking at more items in inventory 
    looking at more items in inventory 
    adding item 6 to shopping basket
    Item 6 added
    looking at more items in inventory 
    adding item 4 to shopping basket
    looking at more items in inventory 
    Item 4 added
    looking at more items in inventory 
    looking at more items in inventory 
    adding item 2 to shopping basket
    Item 2 added
    looking at more items in inventory 
    finished shopping. result: List(Success(1), Success(1), Success(1), Success(1), Success(1))
    

    进程已完成,退出代码为0

    以下代码似乎可以工作,但为什么当打印显示它们是成功时,我必须将结果元素视为Future[Int](1)?

    //y seem to be Future[Int]
    //y.value is Option(Success(1))
    //v.get is calling 'get' on Success
    val total = result.foldLeft(0)((x,y)=>y.value match {
        case Some(v)=>x+v.get
        case None=>x
      })
      println("finished shopping. result: " +result + "total "+total)
    
    
    finished shopping. result: List(Success(1), Success(1), Success(1), Success(1), Success(1))total 5
    
  • 共有2个答案

    陈文景
    2023-03-14
    Future.foldLeft(futures)(0)(_ + _).foreach(result => "finished shopping. result: " +result)
    
    阎麒
    2023-03-14

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

    val result: Int = Await.result(Future.sequence(futures).map(_.sum), 5 seconds)
    

    请注意,Await.result仅用于在所有期货完成之前测试不会过早终止。

    为什么我必须将结果元素视为未来[Int],当印刷品显示它们是成功的(1)?

    因为是未来[T]。值返回一个选项[Try[T]],其中Try可以是成功失败。但它只会在未来完成时返回一个值。我不会使用<code>走上一条路。值。

     类似资料:
    • 我想创建一个未来列表,每个未来都可能通过或失败,并整理成功未来的结果。我该怎么做? 问题1)我想等待每个未来完成2)我想从每个成功的未来收集返回值的总和,并忽略失败的回报值(所以我应该得到3)。

    • 如何在Scala中调试代码?

    • 我有三个连续的未来,并在理解中使用 现在我有一个像List[Future[T]这样的未来列表,首先我使用这种方法将其转移到Future[List[T]](为什么这个未来列表到未来列表的转换编译和工作?)。然后我得到未来

    • 问题内容: 我正在尝试kafka.utils.ZKStringSerializer用clojure创建一个scala对象。(在org.apache.kafka/kafka_2.10 “0.8.0”) 由于我对scala知之甚少,所以我不知道如何调用它的构造函数。我这样尝试过: 并得到一个错误: 我尝试使用来查看其方法,但是只有一些静态方法。并告诉我这是一类,而不是我想要的实例。 该对象的实现如下: