我想要一种方法来发送请求,然后通过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的方法正确?
答案 0 :(得分:0)
这是一个看起来不错的解决方案
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"));
}
答案 1 :(得分:0)
如果您的execute
将Class<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>
...