使用CompletableFuture进行回调

wax*_*cal 0 java multithreading callback

我正在尝试使用一些字符串创建一个非常简单的回调.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!");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 6

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

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

  • Function传递到exceptionally要消耗Throwable并返回一个替代的结果.

此外,您正在调用一个static使用表达式new CompletableFuture<String>()作为其目标的方法,并且您有一个过时的字符串创建表达式,就像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!"));
Run Code Online (Sandbox Code Playgroud)

这似乎是你的意图.如果确保MakesANetworkCall正确实现Supplier<String>,则应该编译而不发出任何警告.


Old*_*eon 5

您的核心问题在于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;
                }
            });
Run Code Online (Sandbox Code Playgroud)