嗨,我正在研究Scala Future,以及在Future/Promises中获取内部数据的方法。所以我写了所有内容我所了解的模型,获取Scala Futures的内部数据。
我们总是看到这两种情况:
1- 有时我们会在异步函数 block 中获取 future 的内部数据,例如map,flatMap,foreach,fold,...
2-有时我们会在 Future 中得到结果,例如使用 Await
在此示例中,我使用 Akka
?
或 ask
函数(它是异步的),并且我尝试了解最佳实践如何得到 future 的结果
1- 出 block ?
2- 进入阻止?
- 我们知道,异步时阻塞是不好的做法(因此使用
Await
、Sleep
等)都是不好的。
请帮助我找到最佳实践,替换 Await
或 Future.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")
}
最佳答案
最佳实践是“在世界末日”进行 Await。这意味着您应该将所有 future 合并到一个 future 中,然后仅等待一次。
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。这是错误的,因为它违背了使用 Future 的目的。
因此,您的目标是使用 for
组合尽可能多的 future,然后仅等待一次。
除了第 4 种之外,您上面列出的其他解决方案也都可以,因为如果 future 尚未完成,它可能会导致您的程序崩溃。
关于scala - 获取 Scala Future 的内部数据 **最佳案例**,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49920677/