简体   繁体   English

Streams peek() 的 CompletableFuture 等价物是什么?

[英]What is the CompletableFuture equivalent of Streams peek()?

An answer here quotes a table of all CompletableFuture methods, but it's not quite what I'm looking for, or perhaps I'm going about it wrong.这里的答案引用了所有 CompletableFuture 方法的表格,但这并不是我正在寻找的,或者我可能做错了。

I'm looking for the CompletableFuture equivalent of Streams' peek() , so basically a thenApply that returns the input argument or a thenRun that doesn't return Void .我正在寻找与 Streams 的peek()等效的 CompletableFuture,因此基本上是返回输入参数的thenApply或不返回VoidthenRun There are two ways I can think of that both don't semantically accurately express my intention, but do the job:我可以想到两种方式,它们都不能在语义上准确表达我的意图,但可以完成工作:

(..)
.thenApply((a) -> {
   doSomething();
   return a;
}
(..)

and

(..)
.whenComplete((result, exception) -> {
   if (exception == null) {
      doSomething();
   }
}
(..)

Both take the input from the previous stage, allow me to perform an action and return with the same type to the next stage.两者都接受前一阶段的输入,允许我执行一个动作并以相同的类型返回下一阶段。 Of these two the latter second approach limits my timing to when everything else is done, rather than async as soon as the previous necessary stage is complete.在这两种方法中,后第二种方法将我的时间限制在完成其他所有事情的时间,而不是在前一个必要阶段完成后立即异步。

I've also been searching for an identity function that takes a consumer function as argument, but it seems I would have to write that myself:我也一直在寻找一个以消费者 function 作为参数的身份 function,但似乎我必须自己写:

public static <T> Function<T, T> identityConsumer(Consumer<T> c) {
    return a -> { c.accept(a); return a; };
}
(..)
.thenApply(identityConsumer(a -> doSomething()));
(..)

So short of writing my own util functions, is there an elegant way of performing an action in an intermediate stage, where I don't have to return something, while keeping the stage's current type?这么短的编写我自己的 util 函数,是否有一种优雅的方式在中间阶段执行操作,我不必返回某些东西,同时保持阶段的当前类型?

Unlike with Stream , you can make multiple function chains from a single future, so it is not necessary to do everything in a single chain of calls.Stream不同,您可以从一个未来创建多个 function 链,因此无需在单个调用链中完成所有操作。 I would approach your problem like so:我会这样处理你的问题:

var f1 = CompletableFuture.supplyAsync(...);
f1.thenRun(() -> doSomething()); // this is your "peek"
var f2 = f1.thenApply(...); // continue your chain of operations here

I wanted to do this too, so I just made my own wrapper:我也想这样做,所以我自己做了一个包装器:

/** Converts a Consumer into an identity Function that passes through the input */
public static <T> Function<T, T> peek(Consumer<T> fn) {
    return (t) -> {
        fn.accept(t);
        return t;
    };
}

used like:像这样使用:

.thenApply(Functions.peek(SomeUtil::yourConsumerMethod));

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

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