为了账号安全,请及时绑定邮箱和手机立即绑定

什么是 Futures.transform() lambda 参数,以防原始 ApiFuture

什么是 Futures.transform() lambda 参数,以防原始 ApiFuture

米脂 2021-11-24 18:47:42
我有一个异步发送消息列表的方法。每次发送都会返回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 吗?
查看完整描述

1 回答

?
交互式爱情

TA贡献1712条经验 获得超3个赞

ApiFuture<V>在 type 上形成一个monadV,transform并将一个函数应用于type的封装值V。如果由于失败或取消ApiFuture<V>而不包含V值,则转换后的未来是相同的。


如果您想处理由于异常导致的失败,您可以使用ApiFutures.catching()来生成替代结果(例如Boolean.FALSE)。


如果要将取消转换为成功值,我相信您需要ApiFuture.addListener直接使用,并让侦听器完成SettableApiFuture您返回的一个。然后侦听器(将在源未来被取消时被调用)可以检查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;

}


查看完整回答
反对 回复 2021-11-24
  • 1 回答
  • 0 关注
  • 651 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信