以下代码使用print语句模拟在线购物。我正在使用Future来模拟我同时向购物篮添加多个项目的场景(我在篮子中添加每个偶数项目)。我最后想要的是,代码会打印出已添加到篮子中的项目数量。
我希望在所有期货执行完毕后,我会选择他们的 成功对象并整理它们的值(添加它们)。这是一部分 我无法编码。
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
以下代码似乎有效,但为什么我必须在打印显示成功(1)时将结果元素视为Future [Int]?
//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
答案 0 :(得分:1)
您可以使用Future.sequence
将List[Future[Int]]
转为Future[List[Int]]
,然后拨打sum
以查看所有项目已添加:
val result: Int = Await.result(Future.sequence(futures).map(_.sum), 5 seconds)
请注意,Await.result
仅用于在未完成所有期货的情况下不会提前终止测试。
为什么我必须将结果元素视为Future [Int] 打印显示他们是成功的(1)?
由于Future[T].value
返回Option[Try[T]]
,其中Try
可以是Success
或Failure
。但是如果未来完成,它只会返回一个值。我根本不会使用.value
。
答案 1 :(得分:1)
Future.foldLeft(futures)(0)(_ + _).foreach(result => "finished shopping. result: " +result)