有趣的地图和平面地图观测-未来,Scala

有趣的地图和平面地图观测-未来,Scala,scala,Scala,我注意到关于map、flatMap和Future的一些有趣的行为,但我无法理解是什么导致了这种行为 //I have 3 Future objects. object ConcurrencyExample extends App { val time = System.currentTimeMillis() val future1 = Future{println("future1");1} val future2 = Future{println("future2");2}

我注意到关于map、flatMap和Future的一些有趣的行为,但我无法理解是什么导致了这种行为

//I have 3 Future objects. 

object ConcurrencyExample extends App {

  val time = System.currentTimeMillis()


 val future1 = Future{println("future1");1}
  val future2 = Future{println("future2");2}
  val future3 = Future{println("future3");3}

//I want to add 1,2 and 3. I can do it using flatMap

val result = future1 flatMap (f1=> future2.flatMap(f2 => future3.map(f3=> f3+f2+f1) ) )

result onComplete{
    case Success(v)=>println("result is "+v)
    case Failure(e) =>println("failed result:"+e)
  }


  Thread.sleep(1000)
}
结果

future2
future1
future3
result is 6
future3
future2
future1
result is List()
future3
future2
future1
result is Success(3)
如果我将上面的代码更改为map,则会得到一个空列表()。我无法跟踪此空列表的来源

val result = future1 map (f1=> future2.map(f2 => future3.map(f3=> f3+f2+f1) ) )
结果

future2
future1
future3
result is 6
future3
future2
future1
result is List()
future3
future2
future1
result is Success(3)
如果我只使用两个未来的对象和映射,我会获得成功(3),而不是一个空列表()

结果

future2
future1
future3
result is 6
future3
future2
future1
result is List()
future3
future2
future1
result is Success(3)

在第一种情况下,结果返回类型为
Future[Int]
,在第二种情况下,结果返回类型为
Future[Future[…]]
(某些嵌套的Future)

在第一种情况下,当您执行onComplete时

val result: Future[Int] = ???

result onComplete { println }
上述代码将返回
Success(1)

在第二种情况下

val result: Future[Future[..]] = ???

result onComplete { println }
这可能会导致未评估的未来,这就是为什么您会看到
List()
。请参见下面的Scala repl输出。查看
Future{Thread.sleep(1000);1}

scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global

scala> val f = Future { Thread.sleep(1000); 1 }
f: scala.concurrent.Future[Unit] = List()

scala> f onComplete { println }
Success(1)
建议


了解flatMap和map之间的区别,并知道何时使用flatMap和map。

在第一种情况下,结果返回类型为
Future[Int]
,在第二种情况下,结果返回类型为
Future[Future[…]
(一些嵌套的Future)

在第一种情况下,当您执行onComplete时

val result: Future[Int] = ???

result onComplete { println }
上述代码将返回
Success(1)

在第二种情况下

val result: Future[Future[..]] = ???

result onComplete { println }
这可能会导致未评估的未来,这就是为什么您会看到
List()
。请参见下面的Scala repl输出。查看
Future{Thread.sleep(1000);1}

scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global

scala> val f = Future { Thread.sleep(1000); 1 }
f: scala.concurrent.Future[Unit] = List()

scala> f onComplete { println }
Success(1)
建议


了解flatMap和map之间的区别,并知道何时使用flatMap和map。

如果升级到最新版本的Scala 2.11或直接升级到Scala 2.12.x,那么您将看到比“List()”更好的字符串表示法,有关Viktor所说内容的详细信息见。请注意,Scala 2.11.9尚未发布,因此还没有正式的2.11版本提供该修复程序(2.11 nightlies有)。如果您升级到Scala 2.11的最新版本或直接升级到Scala 2.12.x,那么您将看到一个比“List()”更好的字符串表示形式,有关Viktor所说内容的详细信息见。请注意,Scala 2.11.9尚未发布,因此还没有正式的2.11版本和修复程序(2.11晚间版也有)。