繁体   English   中英

在CompletableFuture中链接以返回第一个值

[英]Chaining in CompletableFuture to return first value

我有一些代码可以使用spring-data将实体保存到数据库,然后执行其他一些工作foo()bar() ,这些工作需要已保存的实体的id 看起来像这样:

private CompletableFuture<Void> save(MyEntity me) {
    CompletableFuture<Void> future = ContextAwareCompletableFuture
        .runAsync(() -> repository.save(me))
        .thenRunAsync(() -> foo(me))
        .thenRunAsync(() -> bar(me));
    return future;
}

private Foo foo(MyEntitiy me) {
    // Use the identifier for me to update some foo in another world
}

private Bar bar(MyEntitiy me) {
    // Use the identifier for me to update some bar in at another time
}

现在,我不想从我的save方法返回void 我想返回一个MyEntity所以我尝试了:

private CompletableFuture<MyEntity> save(MyEntity me) {
    CompletableFuture<MyEntity> future = ContextAwareCompletableFuture
        .runAsync(() -> repository.save(me))
        .thenRunAsync(() -> foo(me))
        .thenRunAsync(() -> bar(me));
    return future;
}

这不起作用,因为runAsync返回void。 我的方法repository.save()返回了我希望返回的对象,但是该调用位于链的开头。 我需要先保存对象,然后才能执行foobar

所以我接下来尝试的是:

private CompletableFuture<MyEntity> save(MyEntity me) {
    CompletableFuture<MyEntity> future = ContextAwareCompletableFuture
        .supplyAsync(() -> repository.save(me))
        .thenApplyAsync((e) -> baz(e);
    return future;
}

private MyEntity baz(MyEntitiy me) {
    foo(me);
    bar(me);
    return me;
}

现在,这对我来说似乎是错误的。 FooBar现在必须在同一阶段执行,这可能需要一些时间。

foobar正确完成后,如何返回保存在repository.save()的对象?

如果foobar可以同时运行,则可以选择在save而不是对其进行排序:

private CompletableFuture<MyEntity> save(MyEntity me) {
    CompletableFuture<MyEntity> future = ContextAwareCompletableFuture
        .supplyAsync(() -> repository.save(me));
    CompletableFuture<Void> fooFuture = future
        .thenAcceptAsync((e) -> foo(e));
    CompletableFuture<Void> barFuture = future
        .thenAcceptAsync((e) -> bar(e));
    return future
        .thenCombine(fooFuture, (result, fooResult) -> result)
        .thenCombine(barFuture, (result, barResult) -> result);
}

请注意,我使用thenAcceptAsync而不是thenRunAsync来避免捕获me 最后我也避免了被捕获。

我们能避免一个thenCombine如果我们回到对实体fooFuturebarFuture

private CompletableFuture<MyEntity> save(MyEntity me) {
    CompletableFuture<MyEntity> future = ContextAwareCompletableFuture
        .supplyAsync(() -> repository.save(me));
    CompletableFuture<MyEntity> fooFuture = future
        .thenApplyAsync((e) -> { foo(e); return e; });
    CompletableFuture<MyEntity> barFuture = future
        .thenApplyAsync((e) -> { bar(e); return e; });
    return fooFuture
        .thenCombine(barFuture, (fooResult, barResult) -> fooResult);
}

您可以使用一个可以填充并返回输入的方法进行链接:

.thenApply(e -> { foo(e); return e; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM