在句柄块中执行CompletionStage的正确方法是什么?

时间:2018-10-03 01:08:56

标签: java java-8 completable-future

我正在执行一个CompletionStage,它可能会返回异常-它正在尝试将记录插入数据库。如果出现“重复记录”异常,我想取而代之的是检索已经存在的记录。

这是我的代码:

MyObj obj = new MyObj();
obj.setUserId(userId);
obj.setEventId(eventId);

return database.insert(obj).handle((s, t) -> {
    if(t != null) { //TODO: check exception type
        CompletionStage<MyObj> recover = database.get(userId, eventId).thenApply(opt -> opt.get());
        try {
            return recover.toCompletableFuture().get();
        }
        catch(Exception e) { //TODO: check specific exception types
            throw new CompletionException(e);
        }
    }
    else {
        return obj;
    }
});

这似乎可行,但我认为它看起来很混乱。理想情况下,我想这样做:

MyObj obj = new MyObj();
obj.setUserId(userId);
obj.setEventId(eventId);

return database.insert(obj).handle((s, t) -> {
    if(t != null) { //TODO: check exception type
        return database.get(userId, eventId).thenApply(opt -> opt.get());
    }
    else {
        return obj;
    }
});

“句柄”语法不允许我直接在此处返回CompletionStage / CompletableFuture。因此,我需要对“ toCompletableFuture()。get()”使用混乱的try / catch。

我对CompletionStage / CompletableFuture语法不太熟悉。有没有更好的方法来编写此代码?

1 个答案:

答案 0 :(得分:1)

return database.insert(obj)
    .exceptionally (exception -> database.get(userId, eventId).thenApply(opt -> opt.get()));

您可以使用exceptionally完成此操作。如果引发异常,将执行Function并将结果提供给后续任务,否则将是透明的。