当前位置: 首页 > 知识库问答 >
问题:

Java中promise的概念

逄学潞
2023-03-14

是否有在java中使用Promise(就像在JavaScript中使用ut一样)而不是使用嵌套回调的概念?

如果是这样,是否有一个在java中实现回调和链接处理程序的示例?

共有3个答案

马正初
2023-03-14

如果你想在Java7之前做Promise,“java-Promise”可能会很有用。(当然它适用于Java8)

您可以轻松地控制异步操作,如JavaScript的Promise。

https://github.com/riversun/java-promise

示例

import org.riversun.promise.Promise;
public class Example {

    public static void main(String[] args) {
        Promise.resolve("foo")
                .then(new Promise((action, data) -> {
                    new Thread(() -> {
                        String newData = data + "bar";
                        action.resolve(newData);
                    }).start();
                }))
                .then(new Promise((action, data) -> {
                    System.out.println(data);
                    action.resolve();
                }))
                .start();
        System.out.println("Promise in Java");
    }
}

结果:

Java foobar中的Promise

许嘉珍
2023-03-14

2017年7月20日更新

我想编辑还有一个名为“ReactFX”的库,它应该是JavaFX作为一个反应式框架。据我所见,有许多反应式Java库,由于Play基于反应式主体,我假设这些反应式库遵循相同的非阻塞i/o原则,异步调用从服务器到客户端再返回,同时通信由任何一端发送。

这些库似乎是为客户端设计的,但也可能有一个服务器反应库,但我认为使用Play更明智!使用其中一个客户端反应库。

你可以看看https://www.playframework.com/

在此处实现此功能的

https://www.playframework.com/documentation/2.2.0/api/java/play/libs/F.Promise.html

附加读数https://www.playframework.com/documentation/2.5.x/JavaAsync

由于游戏的工作方式,动作代码必须尽可能快,即无阻塞。那么,如果我们还不能计算结果,我们应该从我们的行动中得到什么回报呢?我们应该回报对结果的promise!

Java 8提供了一个名为CompletionStage的通用promise API。完成阶段

在等待响应时,将阻止web客户端,但不会阻止服务器上的任何内容,并且可以使用服务器资源为其他客户端提供服务。

创建完成阶段

CompletionStage<Double> promiseOfPIValue = computePIAsynchronously();
CompletionStage<Result> promiseOfResult = promiseOfPIValue.thenApply(pi ->
                ok("PI value computed: " + pi)
);

Play asynchronous API方法为您提供了一个完成阶段(CompletionStage)。当您使用播放调用外部web服务时,就是这种情况。libs。WS-API,或者如果您使用Akka来安排异步任务,或者使用play与参与者通信。libs。阿卡

异步执行代码块并获得CompletionStage的一种简单方法是使用CompletableFuture.supplyAsync()助手:

CompletionStage<Integer> promiseOfInt = CompletableFuture.supplyAsync(() -> intensiveComputation());

注意:了解哪些线程代码在哪些promise上运行很重要。这里,密集的计算将只在另一个线程上运行。

您无法通过将同步IO包装在完成阶段(CompletionStage)中,神奇地将其变为异步IO。如果无法更改应用程序的体系结构以避免阻塞操作,那么在某个时候必须执行该操作,并且该线程将阻塞。因此,除了将操作封装在CompletionStage中之外,还需要将其配置为在单独的执行上下文中运行,该上下文已配置了足够的线程来处理预期的并发性。有关更多信息,请参阅了解播放线程池。

使用Actors进行阻塞操作也很有帮助。Actors提供了一个干净的模型来处理超时和故障、设置阻塞执行上下文以及管理可能与服务关联的任何状态。Actors还提供了ScatterGatherFirstCompletedRout等模式来解决同时的缓存和数据库请求,并允许在后端服务器集群上远程执行。但是根据您的需要,Actor可能会被过度使用。

到目前为止,我们一直在返回结果。要发送异步结果,我们的操作需要返回一个CompletionStage

public CompletionStage<Result> index() {
    return CompletableFuture.supplyAsync(() -> intensiveComputation())
            .thenApply(i -> ok("Got result: " + i));
}

默认情况下,动作是异步的。默认情况下,播放动作是异步的。例如,在下面的控制器代码中,返回的结果内部包含在promise中:

public Result index() {
    return ok("Got request " + request() + "!");
}

注意:操作代码是返回Result还是CompletionStage

关于CompletionStage的一些信息

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html

这是@Debosmit Ray在回答CompletableFuture时提到的类的一个子类

这个由领英开发的YouTube视频布里克曼先生解释了一点关于promise的内容

https://youtu.be/8z3h4Uv9YbE?t=15m46s

https://www.youtube.com/watch?v=4b1XLka0UIw

我相信第一个视频给出了一个promise的例子,第二个视频也可能给出一些好的信息,我真的不记得哪个视频有什么内容。

不管怎样,这里的信息都很好,值得研究。

我个人不使用Play,但我已经看了很长很长时间,因为它做了很多非常好的东西。

危飞跃
2023-03-14

是的!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();
   }
}

基本设计是一个半流畅的API,您可以在其中安排:

MyCompletableFuture<String> f = ...; g = ...
   f.then((s -> aStringFunction(s)).thenAsync(s -> ...);
or
   f.andThen(g, (s, t) -> combineStrings).or(CompletableFuture.async(()->...)....
 类似资料:
  • 在提出问题之前,我最终要解决的问题是查询我的Firebase数据库和根据结果编写代码的同步性。一个简单的例子来说明: 在上面的示例中,侦听器在数据库中查找名称。如果找到该名称,则会显示欢迎消息并将“userFound”设置为true。如果找不到名称,“userFound”将保持为false,您可以生成一条user not found消息。 问题是,所有内容都在同一时刻运行,因此您总是会立即收到“未

  • Promise API概览 让我们复习一下我们已经在本章中零散地展开的ES6PromiseAPI。 注意: 下面的API尽管在ES6中是原生的,但也存在一些语言规范兼容的填补(不光是扩展Promise库),它们定义了Promise和与之相关的所有行为,所以即使是在前ES6时代的浏览器中你也以使用原生的Promise。这类填补的其中之一是“Native Promise Only”(http://gi

  • 我看过很多实现,它们看起来都很不一样,我真的无法提炼promise的本质。 如果我不得不猜测它只是一个函数,当回调触发时运行。 有人能在几行代码中实现最基本的promise吗。 例如,从这个答案 片段1 传递给

  • 问题内容: 我很好奇,我该如何在Java中实现概率?例如,如果变量显示的机会是1/25,那么我将如何实现呢?还是其他可能性?请指出我的大致方向。 问题答案: 您将使用Random生成一个随机数,然后根据文字对其进行测试以匹配您尝试实现的概率。 因此给出: 将有1/25的可能性为真(因为返回从0到25(但不包括25)的任何数字的可能性均是偶数)。 您当然也必须这样做。 如下面所指出的,如果获得多个随

  • 问题内容: 如何用Java(如C ++)实现朋友概念? 问题答案: Java没有C++中的friend关键字。但是,有一种方法可以模拟这种情况。实际上可以提供更精确控制的方法。假设您具有类A和B。B需要访问A中的某些私有方法或字段。 usageExample()显示了它是如何工作的。B的实例无权访问A实例的私有字段或方法。但是,通过调用GiveKeyTo(),类B可以获得访问权限。没有其他类可以访

  • 问题内容: 我是Java新手,具有CI的背景,正在研究Khalid Moughal的 书。在第126页上,他举了一个例子 显然,这违反了C的顺序点概念,即您不能在同一顺序点中多次更改变量的值。我的问题是在Java中是否适用相同的顺序点规则 ?可能他只是为了说明前缀一元运算符的概念及其副作用而举了这个例子,但是 在著名的Khalid Moughal 著作中,这样的例子显然违反了该语言的非常基本的规则