繁体   English   中英

使用CompletableFuture进行回调

[英]Callback with CompletableFuture

我正在尝试使用一些字符串创建一个非常简单的回调。 IDE的代码含义是抱怨异常的未经检查的调用。 谁能解决这个问题? 最后的想法是包装一个网络调用,以便返回预期的结果,我可以根据需要添加其他功能。

import java.util.concurrent.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;

public class FuturesTest {

    public static void main(String[] args) throws Exception {
        new FuturesTest().go();
    }

    private void go() throws ExecutionException, InterruptedException {
        CompletableFuture.supplyAsync(new MakesANetworkCall())
                .whenComplete(new BiConsumer<String, String>() {
                    @Override
                    public void accept(String result, String s) {
                        System.out.println(result.toString());
                    }
                })
                .exceptionally(new Function<Exception, Exception>() {
                                   @Override
                                   public Exception apply(Exception e) {
                                       e.printStackTrace();
                                       return e;
                                   }
                               }
                ).thenApplyAsync(new Function<String, String>() {
                    @Override
                    public String apply(String o) {
                        System.out.println("Last action of all!");
                        return null;
                    }
                });

        System.out.println("Main thread will sleep");
        Thread.sleep(2500);
        System.out.println("Program over");
    }

    class MakesANetworkCall implements Supplier {

        @Override
        public String get() {
            try {
                System.out.println("Ground control to Major Tom");
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            int i = 2/0;
            return new String("Major Tom reporting!");
        }
    }
}

首先,您的类MakesANetworkCall实现原始类型Supplier而不是Supplier<String> 这将有效地禁用类型检查并隐藏您所犯的所有错误,因此这不是您应该担心的单个警告,因为这不是代码中唯一的错误:

  • BiConsumer传递给whenComplete应该能够消耗Throwable作为第二个参数。

  • 传递给exceptionallyFunction应该消耗Throwable并返回替代结果。

此外,您正在使用表达式new CompletableFuture<String>()作为目标来调用static方法,并且具有过时的字​​符串创建表达式作为new String("Major Tom reporting!") ,其中简单常量"Major Tom reporting!" 会做。 通常,您似乎总是尝试使用一种不合适的方法,例如,一种旨在消耗您不使用的东西的方法,或者一种用于提供您没有的东西的价值的方法。 考虑一下:

CompletableFuture.supplyAsync(new MakesANetworkCall())
    .thenAccept(result -> System.out.println(result))
    .exceptionally(e -> { e.printStackTrace(); return null;})
    .thenRun(()->System.out.println("Last action of all!"));

这似乎是您的意图。 如果确保MakesANetworkCall正确实现了Supplier<String> ,则应在编译时没有任何警告。

您的核心问题是class MakesANetworkCall implements Supplier { 这使用的是原始类型,因此隐藏了更多问题。 修复该问题,使class MakesANetworkCall implements Supplier<String> {并解决所有随之而来的问题,您将获得:

    CompletableFuture.supplyAsync(new MakesANetworkCall())
            // Not <String, String>
            .whenComplete(new BiConsumer<String, Throwable>() {
                @Override
                public void accept(String result, Throwable t) {
                    System.out.println(result);
                }
            })
            // Not <Exception,Exception>
            .exceptionally(new Function<Throwable, String>() {
                @Override
                public String apply(Throwable t) {
                    t.printStackTrace();
                    // Must return a Streing
                    return t.getMessage();
                }
            }
            ).thenApplyAsync(new Function<String, String>() {
                @Override
                public String apply(String o) {
                    System.out.println("Last action of all!");
                    return null;
                }
            });

像这样声明CompletableFuture.exceptionally

public CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn);

您正在传递给它一个Function<Exception, Exception> ,而应该传递给它一个Function<Throwable, String>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM