u00*_*988 2 java asynchronous callback
是否存在在java中使用promises的概念(就像在JavaScript中使用ut一样)而不是使用嵌套回调?
如果是这样,是否有一个关于如何在java中实现回调并且处理程序被链接的示例?
是的!Java 8称之为CompletableFuture
.它可以让你实现这样的东西.
class MyCompletableFuture<T> extends CompletableFuture<T> {
static final Executor myExecutor = ...;
public MyCompletableFuture() { }
public <U> CompletableFuture<U> newIncompleteFuture() {
return new MyCompletableFuture<U>();
}
public Executor defaultExecutor() {
return myExecutor;
}
public void obtrudeValue(T value) {
throw new UnsupportedOperationException();
}
public void obtrudeException(Throwable ex) {
throw new UnsupportedOperationException();
}
}
Run Code Online (Sandbox Code Playgroud)
基本设计是一个半流畅的API,您可以在其中安排:(
顺序或异步)
(函数或操作)
在完成
i)("then")或
ii)("andThen"和"orThen")
其他人时触发.如:
MyCompletableFuture<String> f = ...; g = ...
f.then((s -> aStringFunction(s)).thenAsync(s -> ...);
or
f.andThen(g, (s, t) -> combineStrings).or(CompletableFuture.async(()->...)....
Run Code Online (Sandbox Code Playgroud)
2017 年 7 月 20 日更新
\n\n我想编辑的是,还有一个名为“ReactFX”的库,它应该是 JavaFX 作为反应式框架。据我所知,有许多响应式 Java 库,并且由于 Play 基于响应式原理,因此我假设这些响应式库遵循相同的非阻塞 I/O 原理、从服务器到客户端的异步调用以及返回,同时让任一端发送通信。
\n\n这些库似乎是为客户端而设计的,但也可能有一个服务器响应式库,但我认为使用 Play 会更明智!使用这些客户端反应式库之一。
\n\n你可以看看https://www.playframework.com/
\n\n它在这里实现了这个功能
\n\nhttps://www.playframework.com/documentation/2.2.0/api/java/play/libs/F.Promise.html
\n\n补充阅读https://www.playframework.com/documentation/2.5.x/JavaAsync
\n\n\n\n\n由于 Play 的工作方式,操作代码必须尽可能快,即非阻塞。那么,如果我们还无法计算结果,我们应该从操作中返回什么?我们应该回报一个结果的承诺!
\n\nJava 8 提供了一个名为 的通用Promise API
\n\nCompletionStage
。ACompletionStage<Result>
最终会以类型 的值被赎回Result
。通过使用 aCompletionStage<Result>
而不是普通的 Result,我们能够快速从操作中返回,而不会阻塞任何内容。一旦承诺兑现,Play 将立即提供结果。Web 客户端在等待响应时将被阻塞,但服务器上不会阻塞任何内容,并且服务器资源可用于服务其他客户端。
\n
\n\n\n要创建一个,我们首先
\nCompletionStage<Result>
需要另一个承诺:这个承诺将为我们提供计算结果所需的实际值:
CompletionStage<Double> promiseOfPIValue = computePIAsynchronously();\nCompletionStage<Result> promiseOfResult = promiseOfPIValue.thenApply(pi ->\n ok("PI value computed: " + pi)\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n\nPlay 异步 API 方法为您提供了
\n\nCompletionStage
. 当您使用以下方式调用外部 Web 服务时就会出现这种情况play.libs.WS
,或者使用 Akka 来安排异步任务或使用以下方式与 Actor 进行通信时,就会出现这种情况:play.libs.Akka.
异步执行代码块并获取 a 的一个简单方法
\nCompletionStage
是使用CompletableFuture.supplyAsync()
助手:
CompletionStage<Integer> promiseOfInt = CompletableFuture.supplyAsync(() -> intensiveComputation());\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n\n注意:了解哪些线程代码在哪些Promise上运行很重要上运行很重要。在这里,密集的计算将仅在另一个线程上运行。
\n\n您可以将\xe2\x80\x99t 神奇地将同步 IO 包装在
\n\nCompletionStage
. 如果您无法更改应用程序 xe2x80x99 的体系结构以避免阻塞操作,则在某些时候必须执行该操作,并且该线程将被阻塞。因此,除了将操作封装在CompletionStage
,还需要将其配置为在单独的执行上下文中运行,该执行上下文已配置了足够的线程来处理预期的并发性。有关详细信息,请参阅了解 Play 线程池。使用 Actor 进行阻塞操作也很有帮助。Actor 提供了一个干净的模型来处理超时和失败、设置阻塞执行上下文以及管理可能与服务关联的任何状态。Actor 还提供了类似的模式
\nScatterGatherFirstCompletedRouter
处理同时缓存和数据库请求之类的模式,并允许在后端服务器集群上远程执行。但根据您的需要,演员可能会过度杀伤力。
\n\n\n我们一直在回来
\nResult
到目前为止要发送异步结果,我们的操作需要返回CompletionStage<Result>:
public CompletionStage<Result> index() {\n return CompletableFuture.supplyAsync(() -> intensiveComputation())\n .thenApply(i -> ok("Got result: " + i));\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n\n默认情况下,操作是异步的\n 默认情况下,播放操作是异步的。例如,在下面的控制器代码中,返回的 Result 内部包含在一个Promise中中:
\n
public Result index() {\n return ok("Got request " + request() + "!");\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n\n注意:无论操作代码返回 Result 还是
\nCompletionStage<Result>
,这两种返回的对象在内部都以相同的方式处理。只有一种 Action,它是异步的,而不是两种(同步的和异步的)。返回一个CompletionStage
是一种编写非阻塞代码的技术。
一些信息CompletionStage
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html
\n\n这是 @Debosmit Ray\'s 答案中提到的类的子类CompletableFuture
LinkedIn 开发者 Brikman 先生的这个 Youtube 视频解释了一些关于 Promises 的内容
\n\nhttps://youtu.be/8z3h4Uv9YbE?t=15m46s
\n\n和
\n\nhttps://www.youtube.com/watch?v=4b1XLka0UIw
\n\n我相信第一个视频给出了一个承诺的例子,第二个视频也可能提供一些好的信息,我不太记得哪个视频有什么内容。
\n\n不管怎样,这里的信息都非常好,值得研究。
\n\n我个人不使用 Play,但我已经关注它很长时间了,因为它做了很多非常好的东西。
\n