CompletableFuture |然后应用Async与thenCompose及其用例 [英] CompletableFuture | thenApplyAsync vs thenCompose and their use cases

查看:193
本文介绍了CompletableFuture |然后应用Async与thenCompose及其用例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解CompletableFuture,并遇到了2个方法,然后是ApplyAsync然后是Make。
我试图了解这两者之间的区别。

I was trying to understand CompletableFuture, and came across 2 methods, thenApplyAsync and thenCompose. Am trying to understand the difference between these two.

CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
    System.out.println(Thread.currentThread().getName() + " Printing hello");
    return "Hello";
}).thenCompose((String s) -> {
  return CompletableFuture.supplyAsync(() -> {
      System.out.println(Thread.currentThread().getName() + " Adding abc");
      return "abc "+s;});
}).thenApplyAsync((String s) -> {
    System.out.println(Thread.currentThread().getName() + " Adding world");
    return s + " World";
}).thenApplyAsync((String s) -> {
    System.out.println(Thread.currentThread().getName() + " Adding name");
    if (false) {
       throw new RuntimeException("Oh no exception");
    }
    return s + " player!";
}).handle((String s, Throwable t) -> {
    System.out.println(s != null ? s : "BLANK");
    System.out.println(t != null ? t.getMessage() : "BLANK Exception");
    return s != null ? s : t.getMessage();
});

我如何将这些方法解释为, thenApplyAsync 将在不同的线程中执行提供的函数并返回结果,但在内部它被包装在CompletionStage中。然而, thenCompose 将获得返回对CompletionStage的引用。

How I interpreted these methods as, thenApplyAsync will execute the supplied function in a different thread and return a result, but internally it is wrapped inside a CompletionStage. Whereas, thenCompose will get the return a reference to a CompletionStage.

所以在什么情况下,我会使用 thenCompose over thenApplyAsync

So under what scenarios, will I use thenCompose over thenApplyAsync?

通过此链接,但是它讨论的是 thenApply ,这有些不同:
CompletableFuture | thenApply vs thenCompose

Went through this link, but it was talking about thenApply, which is somewhat different: CompletableFuture | thenApply vs thenCompose

推荐答案

当你使用 thenCompose 时当你的操作没有返回<$ c时,你有一个返回 CompletionStage thenApply 的操作$ C> CompletionStage 。 - >这是在 thenApply vs thenCompose

You would use thenCompose when you have an operation that returns a CompletionStage and thenApply when you have an operation that doesn't return a CompletionStage. -> This is was is in thenApply vs thenCompose

然而 CompletionStage 界面的 Async 变体有微妙的差异和罕见的用例。

However the Async variants of the CompletionStage interface have subtle difference and rare use cases.

让我们考虑这个例子:

import java.util.concurrent.CompletableFuture;

public class Futures {

    public static void main(String[] args) throws InterruptedException {

        CompletableFuture<Void> c = CompletableFuture.runAsync(() -> {

            System.out.println("run1: " + Thread.currentThread().getId());
        });

        c.whenComplete((r, t) -> {
            System.out.println("I'm completed");
        });

        c.thenCompose(__ -> {
            System.out.println("thenCompose1: " + Thread.currentThread().getId());
            return CompletableFuture.runAsync(() -> {
                System.out.println("run2: " + Thread.currentThread().getId());
            });
        }).thenRunAsync(() -> {
            System.out.println("RunAsync1: " + Thread.currentThread().getId());
        });

        Thread.sleep(5000);

        System.out.println("Finished");
    }
}

输出类似于:

run1: 11
thenCompose1: 11
run2: 12
I'm completed
RunAsync1: 11
Finished

请注意 thenApplyAsync 与影响 CompletionStage 的完成状态的非异步变量相比,不会影响原始未来的完成状态。

Notice that thenApplyAsync doesn't not affect the original future's completed state in contrast with the non async variants which do affect the completed state of the CompletionStage.

当你有2个需要按顺序执行的异步操作时,你可能 thenCompose

You might thenCompose when you have 2 asynchronous operations that need to be executed sequentially:

static CompletionStage<String> insert(Object database) {
    throw new UnsupportedOperationException();
}

static CompletionStage<Object> get(String id) {
    throw new UnsupportedOperationException();
}

public static void main(String[] args) throws InterruptedException {

    Object db = new Object(); // pretend this connects to a database
    CompletionStage<Object> recordInserted = insert(db).thenCompose(id -> get(id));
}

您只能在插入记录后检索记录。

You can only retrieve the record after you inserted it.

想象一下,您有一个允许用户注册的应用程序,在注册后他们会收到一封确认电子邮件以确认他们的帐户。

Imagine for a moment that you have an application that allows users to register themselves and upon registration they will receive a confirmation email to confirm their account.

如果邮件服务器关闭或者需要很长时间撰写电子邮件或执行其他检查,您不希望用户等待。

You don't want the user to be waiting for ever if the mail server is down or if it takes a long time to compose the email or perform additional checks.

您然后使用 thenApplyAsync 来启动发送电子邮件逻辑,因为它对您的系统并不重要。用户总是可以回去说给我发送另一封电子邮件

You would then use thenApplyAsync to fire off the send email logic because it is not crucial to your system. A user can always go back and say "send me another email"

static CompletionStage<String> register(String username) {
    throw new UnsupportedOperationException();
}

static void sendConfirmationEmail(String username) {
    throw new UnsupportedOperationException();
}

public static void main(String[] args) throws InterruptedException {

    register("user").thenAcceptAsync(username -> sendConfirmationEmail(username));

}

此处您的系统将在注册完成后作出响应,但它不会等待发送电子邮件,从而提高系统的响应能力。

Here your system will respond when the registration is complete but it will not wait for the email to be sent resulting in improved responsiveness of your system.

到目前为止,我发现异步的用例变种很少但确实存在。

The uses cases I've found so far for the Async variants are scarce but they do exist.

这篇关于CompletableFuture |然后应用Async与thenCompose及其用例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆