Java:将多个可完成的期货组合在一起

问题描述

我想要一种方法来发送请求,然后通过UDP接收响应。 这是我目前开发的内容:

public <T extends ObjectSerializable,U extends ObjectDeserializable>
CompletableFuture<Object> execute(T request,U response)
{
    var resultFuture = sender.asyncSend(request); /*CompletableFuture<Void>*/
    resultFuture.thenAccept((nullObj) -> {
        try {
            receiver.asyncReceive(response).get(); /*CompletableFuture<Void>*/
        }catch (Exception e) {
            throw new FutureExecutionException(e.getMessage());
        }
    }).thenRun(()  -> {
        System.out.println("Send->Receive finished");
    });

    return resultFuture;
}

问题是:我是否必须等待.thenAccept内部的未来?是否可以保证.thenRun将在receive.asyncReceive完成之后执行? 我是否在以这种方式组合CompletableFutures的方法正确?

解决方法

这是一个看起来不错的解决方案

public <T extends ObjectSerializable,U extends ObjectDeserializable>
CompletableFuture<Void> execute(T request,U response)
{
    return sender.asyncSend(request)
            .thenCompose( result -> receiver.asyncReceive(response))
            .thenRun( () -> System.out.println("Send-Receive finished"));
}
,

如果您的executeClass<U>作为参数,这会容易得多。然后,您可以将该类传递给receiver.asyncReceive。在内部,您可以(假设此类具有默认构造函数)创建一个实例,并使用所有字段填充该实例。通过以下方式相当简单:

clazz.getConstructor().newInstance()

然后您的代码将返回CompletableFuture<Response>,因此您的方法将变为:

    public <T extends ObjectSerializable,U extends ObjectDeserializable>
              CompletableFuture<U> execute(T request,Class<U> response){
         return sender.asyncSend(request)
                      .thenCompose(nothing -> receiver.asyncReceive(response));
    }

我也不确定您的asyncSend是否应该返回CompletableFuture<Void>,也许这也可以将Class<U>作为参数并返回正确的类型为{{ 1}},但是我猜您不需要CompletableFuture<U> ...

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...