只有当前一个期货发生异常时,才会执行一个可完成的期货列表。

问题描述 投票:0回答:1

我有一个可完成的期货列表,我想从第一个期货开始,如果有任何完成异常,我想尝试列表中的下一个期货,以此类推,直到我用完所有的期货。如果任何一个期货成功,我想停止在那里,而不使用列表中的下一个期货。我怎样才能实现这个目标呢?到目前为止,我已经尝试过这个方法。


for (SampleFutures future : getSampleFutures()) {

    try {
          return future.someMethod();
      } catch (Exception e) {
          log.error("An exception occurred, Will try the next future.", e);
      }
}

但是当我测试这个方法的时候,我看到当有什么东西失败的时候 未来完成的异常就会被抛出,下一组期货就不会被尝试。

编辑。

这就是SampleFtures的样子

public class SampleFutureA implements SampleFutures {

    @Override
    public CompletableFuture<SomeOject> someMethod() {
        return CompletableFuture
                .supplyAsync(() -> someOtherMethod())
                .thenApply( ()->anotherMethod())
                .exceptionally(ex -> exceptionHandler(ex));
    }
java future completable-future
1个回答
1
投票

对于这种问题,我建议使用 EA异步 因为它提供了一种asyncawait的机制,使得它很容易实现。

当你的应用程序启动时,初始化async(你也可以对应用程序进行预处理,读到的是 文件 详见)

Async.init();

然后用 await() 如下所示。

for (SampleFutures future : getSampleFutures()) {
    try {
        return completedFuture(await(future.someMethod()));
    } catch (Exception e) {
        log.error("An exception occurred, Will try the next future.", e);
    }
}
throw new RuntimeException("All futures failed!");

但是,如果你不能或不想使用它,你可以用一个递归异步方法来实现同样的事情。

private CompletableFuture<SomeObject> processNext(Iterator<SampleFutures> iterator) {
    if (iterator.hasNext()) {
        return iterator.next().someMethod()
                .handle((r, e) -> {
                    if (e != null) {
                        log.error("An exception occurred, Will try the next future.", e);
                        return processNext(iterator);
                    } else {
                        return completedFuture(r);
                    }
                }).thenCompose(c -> c);
    }
    CompletableFuture<SomeObject> allFailed = new CompletableFuture<>();
    allFailed.completeExceptionally(new RuntimeException("All futures failed!"));
    return allFailed;
}

你可以用一个递归的异步方法来实现同样的事情

return processNext(getSampleFutures().iterator());

这个方法会调用第一个未来,只有当它失败的时候,它才会递归地调用自己的异步,从而调用下一个。

不幸的是,我们不得不用 hande() + thenCompose(c -> c) 因为没有 "compose "版本的 handle()exceptionally(). 所以... handle() 返回一个 CompletableFuture<CompletableFuture<SampleObject>>thenCompose() 只是解开它。

© www.soinside.com 2019 - 2024. All rights reserved.