简体   繁体   English

Scala模式:对于产生未来的理解力[A]

[英]Scala Pattern: For Comprehension that Yields a Future[A]

What is the pattern used in Scala to deal with the scenario: Scala用于处理场景的模式是什么:

You have a bunch of futures (they can be whatever, but for the sake of example...) 您有一堆期货(它们可以是任何东西,但是为了示例……)

val aF = Future { true }
val bF = Future { Option(3) }
val cF = Future { myObject }

and you have some function that returns a future 你有一些返回未来的功能

def fooF: Future[SomeObject]

I want to do something like: 我想做类似的事情:

for {
    a <- aF
    b <- bF
    c <- cF
} yield {
    if (a) {
        // do stuff with b & c
        fooF
    } else {
        Future.successful(SomeObject)
    }
}

I want to return a value of Future[SomeObject] , but I call fooF inside of the yield statement, I will get a Future[Future[SomeObject]] 我想返回Future[SomeObject]的值,但是我在yield语句内调用fooF,我会得到Future[Future[SomeObject]]

Here is another solution : 这是另一种解决方案:

def doStuffWith(a: A, b: B, c: C): Future[SomeObject] = if (a) {
  // do stuff with b & c
  fooF
} else Future.successful(SomeObject)

for {
  a <- aF
  b <- bF
  c <- cF
  d <- doStuffWith(a, b, c)
} yield d

As discussed in @laughedelic answer, this is a subjective view, but I believe this way to be more readable, and maintainable (taking out the function always to unit test it, for instance). 正如@laughedelic答案中讨论的那样,这是一个主观观点,但是我认为这种方式更具可读性和可维护性(例如,始终删除该功能以对其进行单元测试)。

  • In Scala 2.12 Future has a flatten method: 在Scala 2.12中, Future具有flatten方法:

    Creates a new future with one level of nesting flattened, this method is equivalent to flatMap(identity). 创建一个具有一层嵌套拼合的新未来,此方法等效于flatMap(identity)。

    So you can write for { ... } yield { ... } flatten . 因此,您可以写成for { ... } yield { ... } flatten

  • In Scala <2.12 you can achieve the same with flatMap(identity) (as mentioned above) 在Scala <2.12中,您可以使用flatMap(identity)实现相同的功能flatMap(identity)如上所述)


An alternative solution is to use flatMap instead of for-comprehension: 另一种解决方案是使用flatMap而非理解:

aF.flatMap { a =>
  if (a) {
    (bF zip cF).flatMap { (b, c) =>
      // do stuff with b & c
      fooF
    }
  } else 
    Future.successful(SomeObject)
  }
}

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

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