第一个 for-callback 几乎每次都打印未来列表,第二个 onComplete-callback 很少 returns 成功(从不失败)
First for-callback prints future list almost every time, second onComplete-callback rarely returns success (never failure)
我正在查看一些 Future 示例。我有一个 Future,它从一个方法中检索一个列表。我调用了两种不同类型的回调,一个 Foreach 回调和一个 onComplete 回调,只是为了尝试一下。
- 几乎每次 return 列表时 Foreach 回调。
- 即使 For 回调 return 编辑了列表,onComplete 回调也很少 return 成功。
- onComplete 回调永远不会 return 失败。
有人可以向我解释一下发生了什么吗?
我了解回调确实并发执行,并且没有顺序。但是如果 Future 正在 return 将列表发送到 Foreach 并且 onComplete 回调在 Foreach 和 Future 之前执行并且它试图从不成功的 Future 中获取列表,那么 onComplete 回调 return 不应该失败吗?
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
object FuturesExampleObj extends App {
println("Using Future to retrieve list\n")
val l: Future[List[String]] = Future {
getList()
}
println("FOR CALLBACK --------------------\n")
l foreach {
items =>
for(item <- items) println(s"foreach item : $item")
println("\n")
}
println("onComplete CALLBACK --------------------\n")
l onComplete {
case Success(i) => println(s"SUCCESS : $i")
case Failure(i) => println(s"FAILURE : $i")
}
def getList(): List[String] ={
val list = ("a" :: "b" :: "c" :: "d" :: "e":: Nil)
list
}
}
结果示例 1(常见)
Using Future to retrieve list
FOR CALLBACK --------------------
onComplete CALLBACK --------------------
foreach item : a
foreach item : b
foreach item : c
foreach item : d
foreach item : e
Process finished with exit code 0
结果示例 2(不常见)
Using Future to retrieve list
FOR CALLBACK --------------------
onComplete CALLBACK --------------------
Process finished with exit code 0
结果示例 3(非常罕见)
基本上 onComplete 永远不会 return 成功或失败。有时,在极少数情况下,它会 return "SUCCESS: " + 列出。
原因是应用程序的线程在 Future
完成之前完成。
只需在程序的和处添加 Await.ready(l, Duration.Inf).value.get
。
这样做只是为了测试!
这是因为你必须明确阻止未来。
在您的情况下,主线程在 onComplete
完成之前终止,有时在 l foreach ..
完成之前终止。
请补充:
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
val listF = l foreach {
items =>
for(item <- items) println(s"foreach item : $item")
println("\n")
}
Await.result(listF, 5 seconds)
这样你就可以等待这个未来的完成。
如果要等待onComplete
,则需要使用Thread.sleep
(在onComplete
之后添加,例如:
l onComplete {
case Success(i) => println(s"SUCCESS : $i")
case Failure(i) => println(s"FAILURE : $i")
}
Thread.sleep(3000)
onComplete
在 ExecutionContext 中的某个线程上运行,而 Await
在当前线程上运行,并阻塞它直到它完成或超过指定的超时。
因此 onComplete
是非阻塞的,而 Await
是阻塞的。
使用 onComplete
我们不会阻塞 Future
的结果,相反,我们将收到 Success
或 Failure
的回调。
Thread.sleep()
正在阻塞我们的主线程,以便我们可以看到未来的异步结果。
请注意,您不应在生产代码中使用 Await.result
,它用于测试 Future 的输出。
此外,您肯定不会使用 Thread.sleep()
,而是使用 "react" 作为 future 返回的结果。
通常,您会有一些 REST API 调用或其他正在运行并等待未来完成的服务。
我正在查看一些 Future 示例。我有一个 Future,它从一个方法中检索一个列表。我调用了两种不同类型的回调,一个 Foreach 回调和一个 onComplete 回调,只是为了尝试一下。
- 几乎每次 return 列表时 Foreach 回调。
- 即使 For 回调 return 编辑了列表,onComplete 回调也很少 return 成功。
- onComplete 回调永远不会 return 失败。
有人可以向我解释一下发生了什么吗?
我了解回调确实并发执行,并且没有顺序。但是如果 Future 正在 return 将列表发送到 Foreach 并且 onComplete 回调在 Foreach 和 Future 之前执行并且它试图从不成功的 Future 中获取列表,那么 onComplete 回调 return 不应该失败吗?
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
object FuturesExampleObj extends App {
println("Using Future to retrieve list\n")
val l: Future[List[String]] = Future {
getList()
}
println("FOR CALLBACK --------------------\n")
l foreach {
items =>
for(item <- items) println(s"foreach item : $item")
println("\n")
}
println("onComplete CALLBACK --------------------\n")
l onComplete {
case Success(i) => println(s"SUCCESS : $i")
case Failure(i) => println(s"FAILURE : $i")
}
def getList(): List[String] ={
val list = ("a" :: "b" :: "c" :: "d" :: "e":: Nil)
list
}
}
结果示例 1(常见)
Using Future to retrieve list
FOR CALLBACK --------------------
onComplete CALLBACK --------------------
foreach item : a
foreach item : b
foreach item : c
foreach item : d
foreach item : e
Process finished with exit code 0
结果示例 2(不常见)
Using Future to retrieve list
FOR CALLBACK --------------------
onComplete CALLBACK --------------------
Process finished with exit code 0
结果示例 3(非常罕见)
基本上 onComplete 永远不会 return 成功或失败。有时,在极少数情况下,它会 return "SUCCESS: " + 列出。
原因是应用程序的线程在 Future
完成之前完成。
只需在程序的和处添加 Await.ready(l, Duration.Inf).value.get
。
这样做只是为了测试!
这是因为你必须明确阻止未来。
在您的情况下,主线程在 onComplete
完成之前终止,有时在 l foreach ..
完成之前终止。
请补充:
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
val listF = l foreach {
items =>
for(item <- items) println(s"foreach item : $item")
println("\n")
}
Await.result(listF, 5 seconds)
这样你就可以等待这个未来的完成。
如果要等待onComplete
,则需要使用Thread.sleep
(在onComplete
之后添加,例如:
l onComplete {
case Success(i) => println(s"SUCCESS : $i")
case Failure(i) => println(s"FAILURE : $i")
}
Thread.sleep(3000)
onComplete
在 ExecutionContext 中的某个线程上运行,而 Await
在当前线程上运行,并阻塞它直到它完成或超过指定的超时。
因此 onComplete
是非阻塞的,而 Await
是阻塞的。
使用 onComplete
我们不会阻塞 Future
的结果,相反,我们将收到 Success
或 Failure
的回调。
Thread.sleep()
正在阻塞我们的主线程,以便我们可以看到未来的异步结果。
请注意,您不应在生产代码中使用 Await.result
,它用于测试 Future 的输出。
此外,您肯定不会使用 Thread.sleep()
,而是使用 "react" 作为 future 返回的结果。
通常,您会有一些 REST API 调用或其他正在运行并等待未来完成的服务。