我提供了一个执行gRPC调用的api(fnGrpc)并返回一个解析为某个值v的ListenableFuture
(其实现是固定且不可修改的)。
我想提供一个辅助函数(fnHelper):
ListenableFuture
。ExecutionException
。我可以通过使用Futures.transform()
来解决(1):
package myHelper;
ListenableFuture<T> fnHelper() {
return Futures.transform(fnGrpc(), new Function<V, T>() {
@Override
public T apply(V v) {
T t1 = f(v);
return t1;
}
});
}
和来电者:
package myApp;
// ...
try {
T t = fnHelper().get();
} catch (ExecutionException | InterruptedException ex) {
// ...
}
我怎样才能实现(2)同时仍然让fnHelper返回ListenableFuture
并保持非阻塞状态?
我可以让fnHelper自己创建一个额外的线程,我会在fnGrpc上调用.get()
,但还有另一种方法可以避免这个额外的线程吗?
我不是Guava的专家,但似乎你可以使用相同的Futures
实用程序类,特别是catchingAsync
方法,在那里你可以传递一个函数,返回带有回退值的ListenableFuture
(t2
):
ListenableFuture<Integer> faultTolerantFuture = Futures.catchingAsync(originalFuture,
Exception.class, x -> immediateFuture(t2), executor);
然后,您应该能够使用transform
方法进行链接,该方法进行转换:
ListenableFuture<T> fnHelper() {
return Futures.catching(Futures.transform(fnGrpc(), new Function<V, T>() {
@Override
public T apply(V v) {
T t1 = f(v);
return t1;
}
}),
Exception.class, x -> immediateFuture(t2));
}
注意:在最后一个片段中,我使用catching
而不是catchingAsync
来与您问题中的代码保持一致,并且我没有指定执行程序。您可能需要使用带有Async
后缀的方法进行非阻塞处理。