java - 如果原始 ApiFuture / ListenableFuture 失败或取消,Futures.transform() lambda 参数是什么
问题描述
我有一个异步发送消息列表的方法。每次发送返回ApiFuture<String>
(GCP 版本的 Guava's ListenableFuture
)。我需要这个方法来返回一个Future<Boolean>
,所以我
- 为每个创建一个列表依赖项
ApiFuture<String>
- 将结果
ApiFuture<List<String>>
转换为Future<Boolean>
usingApiFutures.transform
方法
ApiFuture< List < String > > allSentFuture = ApiFutures.allAsList(futures);
return ApiFutures.transform(allSentFuture, val -> {
return true;
},
Executors.newCachedThreadPool()
);
我的问题是:val
如果一个或多个原始期货失败/取消,上述 lambda 参数的值是多少?在这种情况下甚至会调用 lambda 吗?
谢谢!
解决方案
ApiFuture<V>
在 type 上形成一个monadV
,transform
并将一个函数应用于 type 的封装值V
。如果由于失败或取消ApiFuture<V>
而不包含V
值,则转换后的未来是相同的。
如果您想处理由于异常而导致的失败,您可以使用它ApiFutures.catching()
来产生替代结果(例如Boolean.FALSE
)。
如果您想将取消转换为成功的值,我相信您需要ApiFuture.addListener
直接使用,并让侦听SettableApiFuture
器完成您返回的 a 。然后监听器(当源未来被取消时将被调用)可以检查isCancelled
以检测这种情况,或者可以捕获并处理CancellationException
.
例如:
/**
* Adapt an iterable of {@link ApiFuture} instances into a single {@code ApiFuture}.
*/
static <T> ApiFuture<Boolean> adaptFutures(Iterable<ApiFuture<T>> futures) {
final SettableApiFuture<Boolean> result = SettableApiFuture.create();
final ApiFuture<List<T>> allFutures = ApiFutures.allAsList(futures);
allFutures.addListener(
() -> {
if (allFutures.isCancelled()) {
result.set(Boolean.FALSE);
return;
}
try {
allFutures.get();
result.set(Boolean.TRUE);
} catch (ExecutionException | InterruptedException ex) {
// Maybe log something here?
//
// Note that InterruptedException is actually impossible here
// because we're running in the listener callback, but the API
// still marks it as potentially thrown by .get() above.
//
// So if we reach here it means that the allAsList future failed.
result.set(Boolean.FALSE);
}
},
// Not normally safe, but we know our listener runs fast enough
// to run inline on the thread that completes the last future.
Runnable::run);
return result;
}
推荐阅读
- javascript - 上传图像的croppie js图像大小是原始图像的7-8倍
- java - 如何比较系统日期和用户日期?
- javascript - 仅从 javascript 数组中获取唯一键,其中键和值都是动态的
- c# - Npgsql 库破坏了 Microsoft TestServer
- javascript - PHP Javascript - 数组多维错误
- qt - 对从 QML 调用的槽使用来自不同类(或命名空间)的 ENUMS
- java - Android Studio 的增量内存使用
- c# - 部署虚拟机时出现 VMExtensionProvisioningError
- java - Firebase Admin SDK:无法找到请求目标的有效认证路径
- c# - 有没有办法从excel文件中删除密码?