我提供了一个 api (fnGrpc)执行 gRPC 调用并返回ListenableFuture
解析为某个值v(其实现是固定且不可修改的)。
我想提供一个辅助函数(fnHelper) that:
对 gRPC 结果进行一些转换处理,并返回一个ListenableFuture
解析为转换后的值t1.
处理 gRPC 调用的失败,并返回一些其他值t2而不是有fnHelper的呼叫者看到ExecutionException
.
我可以使用以下方法解决(1)Futures.transform()
:
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),同时仍然享受乐趣 Helper return aListenableFuture
并保持非阻塞?
我本可以有fnHelper它本身创建了一个额外的线程,我将在其中调用.get()
on fnGrpc,但是还有另一种方法可以避免这个额外的线程吗?
我不是番石榴专家,但似乎你可以使用相同的方法来做到这一点Futures http://google.github.io/guava/releases/23.0/api/docs/com/google/common/util/concurrent/Futures.html实用程序类,特别是方法catchingAsync http://google.github.io/guava/releases/23.0/api/docs/com/google/common/util/concurrent/Futures.html#catchingAsync-com.google.common.util.concurrent.ListenableFuture-java.lang.Class-com.google.common.util.concurrent.AsyncFunction-java.util.concurrent.Executor-,您可以在其中传递返回一个的函数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));
}
Note:在最后一个片段中,我使用了catching
代替catchingAsync
为了与您问题中的代码保持一致,并且我没有指定执行者。您可能需要将这些方法与Async
非阻塞处理的后缀。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)