我在看一些未来的例子。我有一个从方法中获取列表的未来。我调用了两种不同类型的回调,Foreach回调和onComplete回调,只是为了尝试一下。
有人能给我解释一下发生了什么吗?
我知道回调是并发执行的,没有顺序。但是如果Future正在将列表返回给Foreach,而onComplete回调已经在Foreach和Future之前执行,并且它试图从一个不成功的Future获取列表,那么onComplete回调不应该返回失败吗?
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 从不返回成功或失败。有时,很少会返回“SUCCESS:”列表。
这是因为你必须明确地阻止未来。在您的情况下,主线程在<code>onComplete</code>完成之前终止,有时在<code>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)
这样,您将等待这个未来的完成。
如果您想等待on完成
,您需要使用Thread.sleep
(在on完成
之后添加它,例如:
l onComplete {
case Success(i) => println(s"SUCCESS : $i")
case Failure(i) => println(s"FAILURE : $i")
}
Thread.sleep(3000)
onComplete
在 ExecuteContext 中的某个线程上运行,而 Await
在当前线程上运行,并阻止它,直到它完成或超过指定的超时。因此,onComplete
是非阻塞的,而 Await
是阻塞的。
使用< code>onComplete时,我们不会阻止来自< code>Future的结果,而是会收到一个< code >成功或< code >失败的回调。
< code>Thread.sleep()正在阻塞我们的主线程,以便我们可以看到未来的异步结果。
请注意,您不应该在生产代码中使用< code>Await.result,它用于测试未来的输出。此外,您肯定不会使用< code>Thread.sleep(),而是对未来返回的结果做出“反应”。
通常,您将有一些REST API调用或其他服务运行并等待将来完成。
在第一章中,我们探讨了JavaScript中关于异步编程的术语和概念。我们的焦点是理解驱动所有“事件”(异步函数调用)的单线程(一次一个)事件轮询队列。我们还探讨了各种解释 同时 运行的事件链,或“进程”(任务, 函数调用等)间的关系的并发模式。 我们在第一章的所有例子中,将函数作为独立的,不可分割的操作单位使用,在这些函数内部语句按照可预知的顺序运行(在编译器水平之上!),但是在函数顺序水平上,
尝试拯救回调 有几种回调的设计试图解决一些(不是全部!)我们刚才看到的信任问题。这是一种将回调模式从它自己的崩溃中拯救出来的勇敢,但注定失败的努力。 举个例子,为了更平静地处理错误,有些API设计提供了分离的回调(一个用作成功的通知,一个用作错误的通知): function success(data) { console.log( data ); } function failure(er
我用的是parse.com。每个包里面都有很多钻子,每个品类里面都有很多包。 我卡住了。然后(函数(result,result2,result3)在最后一行。promise可以有多个promise,它是可变的。有没有一种方法可以写出如下内容: 谢谢!
复习 回调是JS中异步的基础单位。但是随着JS的成熟,它们对于异步编程的演化趋势来讲显得不够。 首先,我们的大脑用顺序的,阻塞的,单线程的语义方式规划事情,但是回调使用非线性,非顺序的方式表达异步流程,这使我们正确推理这样的代码变得非常困难。不好推理的代码是导致不好的Bug的不好的代码。 我们需要一个种方法,以更同步化,顺序化,阻塞的方式来表达异步,正如我们的大脑那样。 第二,而且是更重要的,回调
延续 让我们回到在第一章中开始的异步回调的例子,但让我稍微修改它一下来画出重点: // A ajax( "..", function(..){ // C } ); // B // A和// B代表程序的前半部分(也就是 现在),// C标识了程序的后半部分(也就是 稍后)。前半部分立即执行,然后会出现一个不知多久的“暂停”。在未来某个时刻,如果Ajax调用完成了,那么程序会回到它刚才离开的
我正在使用JavaFx对GUI进行编程,我真的不知道如何连接所有内容。我有一个主窗口,在主窗口中我有一个按钮可以打开另一个窗口,允许我选择客户。现在我已经在努力将选定客户的信息返回给主窗口,因为我没有打开它的返回方法。 我是这样打开的:public void openSecondWindow(ActionEvent事件){ 我自己没有初始化第二个窗口,也没有像第二个窗口sc=new第二个窗口()这