【问题标题】:Get internal data of Scala Future **BEST CASE**获取 Scala Future 的内部数据 **BEST CASE**
【发布时间】:2018-09-29 22:24:21
【问题描述】:

,我正在研究 Scala Future,获取内部数据的方法在 Future/Promises 中被扭曲了。所以我写了所有我知道的模型,用于获取 Scala Futures 的内部数据。

我们总是看到这两种情况:

1- 有时我们会在 异步函数块中获得 未来的内部数据,例如 map、flatMap、foreach、fold ......

2- 有时我们会在 Future 中得到结果,例如使用 Await

在这个例子中,我使用 Akka ?ask 函数(它是异步的)并且我尝试了解如何获得未来结果的最佳实践

1- 出块?

2-in 阻止?

  • 我们知道当我们异步时阻塞是不好的做法(所以使用AwaitSleep、...)是不好的。

请帮我找到最佳实践替换 AwaitFuture.value.get.get

Tnx !!!

这是我的代码示例:

  //Main Problem
  val futureResult: Future[String] = (ping ? AskingTest).mapTo[String]

  //Solution number 1
  val awaitResult = Await.result(futureResult, myTimeout)
  println(s"(1): $awaitResult")

  //Solution number 2
  val eitherResult: Either[Throwable, String] = Await.ready(futureResult, myTimeout).value.get match {
  case Success(str) => println(s"(2): $str");Right(str)
  case Failure(err) => println(s"(2): $err");Left(err)
 }

  //Solution number 3 ***low speed***
  import scala.concurrent.ExecutionContext.Implicits.global 
  //BadPractice: Writ in play documentation.
  futureResult map { x: String =>
    println(s"(3): $x")
  }

  //Solution number 4
  futureResult.value.get match {
    case Success(str) => println(s"(4): $str")
    case Failure(err) => println(s"(4)$err")
  }

  //Solution number 5
  futureResult onComplete {
    case Success(str) => println(s"(5): $str")
    case Failure(err) => println(s"(5): $err")
  }

【问题讨论】:

    标签: scala async-await future


    【解决方案1】:

    最佳做法是“在世界尽头”执行 Await。这意味着您应该将所有未来合并到一个未来中,然后只等待一次。

    val f1 = (ping1 ? AskingTest).mapTo[String]
    val f2 = (ping2 ? AskingTest).mapTo[String]
    
    val combinedFuture: Future[(String, String)] = for {
      str1 <- f1
      str2 <- f2
    } yield (str1, str2)
    
    // final await at the end of program
    val (str1, str2) = Await.result(combinedFuture, Duration.Inf)
    

    当我开始使用 Futures 编写代码时,我曾经在每一行都写 Await。这是错误的,因为它违背了使用 Futures 的目的。

    所以您的目标是使用for 组合尽可能多的期货,然后只等待一次。

    您上面列出的其他解决方案也可以,除了 No 4,因为如果未来尚未完成,它可能导致您的程序崩溃。

    【讨论】:

    • Tnx!!! ,我认为在结合 Futures 时,我们必须等待最长的 Future。不好的做法也是如此,如果我们需要使用 await 我认为最好在每个未来使用 Await。
    【解决方案2】:

    正如你所说,阻塞是不好的,你应该只在测试中使用它。

    这是一个很好的博客,描述了各种可能性:testing-future-objects-scalatest

    在现实生活中你应该使用例如这个:

      futureResult.foreach { x: String =>
        // do some side effect
      }
    

    您只需确保调用此 Future 的进程没有停止(例如在测试用例中)

    另一种解决方案是使用 Async - Await 构造,该构造在 Scala 中也有实现:scala-async

    【讨论】:

    • @kianjalali 只需将其切换为map;)。我使用了 foreach,因为您的所有示例都使用 println 这是单位。我还添加了 async-await 构造 - 检查一下。
    猜你喜欢
    • 2014-07-24
    • 2017-08-20
    • 1970-01-01
    • 2021-01-18
    • 2018-01-22
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多