简体   繁体   English

顺序运行期货

[英]Running futures sequentially

The objective of the code below is to execute Future f3 or f4 depending on a condition. 以下代码的目的是根据条件执行Future f3f4 Note that the condition depends on the result of Future f1 or f2 , so it has to wait. 请注意,条件取决于Future f1f2的结果,因此必须等待。 This seems to work, however since f1 and f2 are futures this code shouldn't run sequentially. 这似乎可行,但是由于f1f2是期货,因此此代码不应顺序运行。 Is this code correct? 此代码正确吗?

object TestFutures extends App {

  val f1 = Future { 1 }
  val f2 = Future { 2 }
  val f3 = Future { 3 }
  val f4 = Future { 4 }

  val y = 1

  for {
    condition <- if (y>0) f1 else f2
    _ <- if (condition==1) f3.map {a => println("333")} else f4.map {b => println("444")}
  }  yield ()


  Thread.sleep(5000)
}

No it is not correct. 不,这是不正确的。 When you create a Future like you do it, it starts the computations immediately. 当像您一样创建Future时,它将立即开始计算。 Before reaching for comprehension, all of your 4 futures are running already. 到达之前for理解,所有的4个期货已经运行。 You need to create them later, depending on the conditions. 您需要稍后根据条件创建它们。

val y = 1
for {
  condition <- if (y > 0) Future { 1 } else Future { 2 }
  _ <- if (condition == 1) 
    Future { 3 }.map(a => println("333"))
  else 
    Future { 4 }.map(b => println("444"))
} yield ()

It is probably good to extract creating each of those to a method, that you will just call, for sake of readability. 出于可读性考虑,最好将创建的每个方法提取到您将要调用的方法中。

It should be obvious they start running when they are created because you can just say 很明显,它们在创建时就开始运行,因为您可以说

Future(1).map(x => println(x))

and it works without any sort of triggering. 它的工作原理没有任何触发。 Anyway try to run the following code 无论如何尝试运行以下代码

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

def printWhenCompleted[A](f: Future[A]): Future[A] = f.map { x =>
    println(x)
    x
}

val f1 = printWhenCompleted(Future { 1 })
val f2 = printWhenCompleted(Future { 2 })
val f3 = printWhenCompleted(Future { 3 })

for {
  r3 <- f3
  r2 <- f2
  r1 <- f1
} yield r1 + r2 + r3

it should give you those numbers in random order, instead of sequential 3, 2, 1 它应该给你这些数字中随机顺序,而不是连续的3, 2, 1

Edit 编辑

Here is implementation of the first code (without println ) using flatMap 这是使用flatMap实现的第一个代码(不带println

val futureCondition = if (y > 0) Future(1) else Future(2)
futureCondition.flatMap(condition => if (condition == 1) Future(3) else Future(4))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM